2

When I compile the following code (with -Wall), I get no warnings because I cast the *(str)++ to void type. However, if I do not cast that operation to void type, the follow warning is put: warning: value computed is not used [-Wunused-value] Is this the correct way to get rid of compiler warnings?

#include <stdio.h>

static void print(char *str)
{
  while(*str) {
    printf("%c\n", *str); 
    (void)*(str)++;
  }
}

int main(void)
{
  print("Hello");
  return 0;
}
Ryan McCullagh
  • 13,581
  • 8
  • 56
  • 101
  • you don't need the `*` when you increment the pointer. – AShelly Jun 04 '14 at 03:02
  • You incrementing pointer, dereferencing its old value, and doing nothing with the result. That's what warning says. `(void)` is correct way to mark something as 'used' even though it does nothing. But you don't need it here (in fact, it is very rarely needed, usually in macros) - because you don't need value you don't use, so no need to dereference pointer in the first place. – keltar Jun 04 '14 at 03:09

2 Answers2

4

The correct way to get rid of those compilers warnings is to simply do str++;

quantdev
  • 22,595
  • 5
  • 47
  • 84
  • `str++` still has a return value, this shouldn't fix it. – Patrick Collins Jun 04 '14 at 03:13
  • I don't get warnings when doing this. – Ryan McCullagh Jun 04 '14 at 03:15
  • @RPM : you wont, this is valid C. – quantdev Jun 04 '14 at 03:17
  • @quantdev I'm wrong about how gcc works so it seems this does stop the warning, but there's no reason it should -- `*(str++)` and `str++` both return a value -- the former returns a `char`, the latter returns a `char*`. @RPM's question is much more cleanly solved by using a `for` loop than by having a random hanging `str++`. – Patrick Collins Jun 04 '14 at 03:20
  • str++ in a for loop will do exactly the same. Any modern compiler will generate strictly the same machine code for both loops: they are the same ! No need to read the return value for an operator that has side-effect. Edit: but I appreciate discussing this, its positive ! – quantdev Jun 04 '14 at 03:22
  • @quantdev that's true, I just think that `while(foo){ ...; foo++; ...}` is poor style -- that's precisely the reason that we have `for` loops. – Patrick Collins Jun 04 '14 at 03:24
  • Reading a lot of the sysvinit programs from debian, I've seen a pattern of for loops more than while loops. – Ryan McCullagh Jun 04 '14 at 03:25
  • @PatrickCollins there is a good reason why we have while too. And `while(*foo++)`, by the way – keltar Jun 04 '14 at 03:44
  • @keltar `while(*foo++)` doesn't work in this case, since it would increment the pointer before the first `printf` call, or else I would agree that that is cleaner. – Patrick Collins Jun 04 '14 at 03:46
2

This is correct, but you're unnecessarily dereferencing -- you don't need *(str++), just str++. That aside, you probably just want

for(; *str; str++) { 
    printf("%c\n", *str);
}

Instead.

See also this question.

Community
  • 1
  • 1
Patrick Collins
  • 9,307
  • 4
  • 23
  • 60
  • Yes, C has no strings, only `char*`s. A string literal will be a stack-allocated `char*`. `f("some string")` is the same as `char[] tmp = "some string"; f(tmp)`. – Patrick Collins Jun 04 '14 at 03:23
  • A string literal is not usually found on the stack. `char[] tmp = "some string";` may be on the stack if `tmp` is a local variable, but this is the location of `tmp`, not of the string literal `"some string"` which, if it is explicitly represented in memory at all, is probably in a read-only segment somewhere near the code. – Pascal Cuoq Jun 04 '14 at 03:31
  • @PascalCuoq My mistake, thank you for correcting me. – Patrick Collins Jun 04 '14 at 03:32
  • from my research, `char * str = "hello"` is a allocated as static read only memory. – Ryan McCullagh Jun 04 '14 at 03:33