Live data from Hacker News

Declaring C String Constants

eklitzke.org

31–40 of 87 posts

Re: Declaring C String Constants

#31
post #25

There's a big mistake here: // Bogus function, just to see how arguments are passed. void bogus(); // Invoke bogus using ptr. void do_ptr() { bogus(&ptr, ptr); } // Invoke bogus using arr. void do_arr() { bogus(&arr, arr); } "&ptr" and "&arr" are not the same. &ptr gives you a pointer to a pointer (char * *), but &arr just gives you a pointer to the array data. That's why the code is different. This would normally sh…

>(I didn't know that no-arg functions in C are implicitly variadic! That's bizarre. I would have expected modern compilers to disable that by default, but I can't get Clang to warn me about it even with -Wall.) I didn't know that either. I wonder if `void bogus(void)` behaves any differently?

Yes, in C you must use 'void' to indicate that the function takes no arguments. (This is deprecated in C++ in favor to an empty argument list - which breaks backward compatibility with C).

Re: Declaring C String Constants

#32

There's a big mistake here: // Bogus function, just to see how arguments are passed. void bogus(); // Invoke bogus using ptr. void do_ptr() { bogus(&ptr, ptr); } // Invoke bogus using arr. void do_arr() { bogus(&arr, arr); } "&ptr" and "&arr" are not the same. &ptr gives you a pointer to a pointer (char * *), but &arr just gives you a pointer to the array data. That's why the code is different. This would normally sh…

It's not really variadic in the sense that you can't use va_start and friends to access the arguments. Instead, if the actual definition doesn't match the call, it's undefined behavior and the compiler can't catch it.

Re: Declaring C String Constants

#34

There's a big mistake here: // Bogus function, just to see how arguments are passed. void bogus(); // Invoke bogus using ptr. void do_ptr() { bogus(&ptr, ptr); } // Invoke bogus using arr. void do_arr() { bogus(&arr, arr); } "&ptr" and "&arr" are not the same. &ptr gives you a pointer to a pointer (char * *), but &arr just gives you a pointer to the array data. That's why the code is different. This would normally sh…

GCC has -Wstrict-prototypes.

Re: Declaring C String Constants

#35

There's a big mistake here: // Bogus function, just to see how arguments are passed. void bogus(); // Invoke bogus using ptr. void do_ptr() { bogus(&ptr, ptr); } // Invoke bogus using arr. void do_arr() { bogus(&arr, arr); } "&ptr" and "&arr" are not the same. &ptr gives you a pointer to a pointer (char * *), but &arr just gives you a pointer to the array data. That's why the code is different. This would normally sh…

Additionally, he keeps talking about dereferencing the pointer, which I don't think is right. The pointer never gets deferenced in the code shown.

I'm not an x86 guru, but I think that "movq ptr(%rip), %rsi" is different because ptr needs to be moved from relative to the instruction pointer (because it is on the stack, as a non-const variable).

Re: Declaring C String Constants

#36
As others have noted, this is a little bizarre as the two functions are doing different things; one being less performant than the other is not really surprising. That said, there can be advantages to using array syntax rather than pointers for strings (even when also declaring the pointer to be constant), e.g. the compiler "knows" the array "pointer" is non-null:

  extern const char arr[];

  void do_arr() {
    if (arr) {
      dummy();
    }
  }
allows the compiler to optimize out the conditional: https://godbolt.org/g/FwBeWx.

Re: Declaring C String Constants

#38
post #10

Earlier quoted context omitted.

C is not that far removed from assembly, and gives the programmer strong control over how the program operates. It is a tool, and if you need safety over control / performance / portability / etc., then don't use C.

Being a language not far form assembly shouldn't mean being broken and error prone.

Well, it doesn't.

Re: Declaring C String Constants

#39
post #35

There's a big mistake here: // Bogus function, just to see how arguments are passed. void bogus(); // Invoke bogus using ptr. void do_ptr() { bogus(&ptr, ptr); } // Invoke bogus using arr. void do_arr() { bogus(&arr, arr); } "&ptr" and "&arr" are not the same. &ptr gives you a pointer to a pointer (char * *), but &arr just gives you a pointer to the array data. That's why the code is different. This would normally sh…

Additionally, he keeps talking about dereferencing the pointer, which I don't think is right. The pointer never gets deferenced in the code shown. I'm not an x86 guru, but I think that "movq ptr(%rip), %rsi" is different because ptr needs to be moved from relative to the instruction pointer (because it is on the stack, as a non-const variable).

You are right. This is RIP-relative addressing.

Re: Declaring C String Constants

#40
post #29
post #25

Earlier quoted context omitted.

>(I didn't know that no-arg functions in C are implicitly variadic! That's bizarre. I would have expected modern compilers to disable that by default, but I can't get Clang to warn me about it even with -Wall.) I didn't know that either. I wonder if `void bogus(void)` behaves any differently?

Yes it would behave differently. Putting void in the parenthesis tells the compiler the function accepts no arguments at all.

Good to know. I never bothered with `void` inside the argument list in C before (I primarily write C++, very rarely C). I will have to remember to be more explicit when I do write C code in the future.
Post reply on HN