Live data from Hacker News

Declaring C String Constants

eklitzke.org

51–60 of 87 posts

Re: Declaring C String Constants

#51
post #32

Earlier quoted context omitted.

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.

Undefined behavior strikes again! It really seems like the C standard maintainers and compiler vendors should just get together and sort that whole mess out. It can give you a few extra percent in some benchmarks, sure, and help C keep its mostly-deserved reputation as the fastest language, but the cost is huge. If these non-type-checked functions are really useful in some very unusual use case, give it a special wei…

> It really seems like the C standard maintainers and compiler vendors should just get together and sort that whole mess [Undefined behavior] out.

Why do you think there is undefined behavior? Because committee members are lazy?

Not every machine is a C machine (PDP-11). I used to program machines with bytes that could range from 1-36 bits (these are older than the PDP-7/PDP-11 that C was designed for). A joy to program, but the C model did not apply. You may consider these architectures obsolete, and they are, but many decisions in the design of IP, UDP and TCP (and some higher level protocols) still reflect these machines.

Early C standardization efforts bent backwards to support the architectures committee members cared about. Some constraints (undef behavior etc) were removed in later standards (though the C++ committee is more aggressive in this regard than the C committee).

And you well could argue that C's tight coupling to the architecture of the PDP-11 and the programming standards of the 70s holds back CPU design. Many of these undefined areas are places where compilers have the opportunity to take advantage of CPU features (e.g. vector hardware).

The committee mailing list and other discussions are open -- have a read. And if you feel strongly you can even join the committee.

Re: Declaring C String Constants

#52

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.

Try -Wstrict-prototypes, then `void` is required.

Re: Declaring C String Constants

#53

Earlier quoted context omitted.

You're totally right. But wannabe C experts will never accept that. Stupid broken language. The only valid reason why it should be used is for legacy reasons.

I find it funny that your bashing the C language but your screen name is "irundebian" you realize that Debian is almost entirely written in C right? > The only valid reason why it should be used is for legacy reasons. Also there are many projects even today where C is the only choice, like embedded programming, some micro controllers only have a C compiler available.

And because I hate C I should run an operating system written in Rust or Ada or what? Don't understand what's so funny about that.

> Also there are many projects even today where C is the only choice, like embedded programming, some micro controllers only have a C compiler available.

Yes, as I said, for legacy reasons.

Re: Declaring C String Constants

#54
post #51

Earlier quoted context omitted.

Undefined behavior strikes again! It really seems like the C standard maintainers and compiler vendors should just get together and sort that whole mess out. It can give you a few extra percent in some benchmarks, sure, and help C keep its mostly-deserved reputation as the fastest language, but the cost is huge. If these non-type-checked functions are really useful in some very unusual use case, give it a special wei…

> It really seems like the C standard maintainers and compiler vendors should just get together and sort that whole mess [Undefined behavior] out. Why do you think there is undefined behavior? Because committee members are lazy? Not every machine is a C machine (PDP-11). I used to program machines with bytes that could range from 1-36 bits (these are older than the PDP-7/PDP-11 that C was designed for). A joy to prog…

I realize it's there for a reason -- as I understand it, to avoid constraining compilers into generating unnecessarily awkward code for unlikely edge cases. And that fits with one of C's main advantages, being fast and lightweight.

But in the last few years I've read many, many articles about problems that crop up when optimizing C compilers do weird things to reasonable-looking code, citing "undefined behavior" as an excuse. I can't say for sure if I've hit issues like that myself, but I've certainly used libraries that have.

Maybe the problem lies squarely with the compiler vendors, but the language spec enables them.

Re: Declaring C String Constants

#55
post #47

Earlier quoted context omitted.

Undefined behavior strikes again! It really seems like the C standard maintainers and compiler vendors should just get together and sort that whole mess out. It can give you a few extra percent in some benchmarks, sure, and help C keep its mostly-deserved reputation as the fastest language, but the cost is huge. If these non-type-checked functions are really useful in some very unusual use case, give it a special wei…

They did get together to sort the mess out. They did so in the 1980s. Where do you think the idea of "ANSI function prototypes" came from?

It's hardly a complete solution, though, since they kept the zero-arg functions around as a special case!

ANSI C is the version I first learned. I didn't know that weird exception for zero-args functions still existed, or had forgotten it. I could be wrong, but I bet most C programmers don't know about it.

Re: Declaring C String Constants

#56
post #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.

Strange that that isn't included in -Wall! I knew -Wall isn't the same as -Weverything, but I'm always surprised at what it omits. Why wouldn't you want that warning?

Edit to add: Aha, my 'gcc' was actually Clang because I'm on OS X. Installing the real GCC, I find:

gcc -Wstrict-prototypes does what I want and disallows this feature. But -Wall doesn't include that flag, and GCC doesn't seem to have -Weverything.

Clang accepts -Wstrict-prototypes but doesn't catch no-arg functions! That's bad. Even with -Weverything, Clang lets you do anything you want with no-arg functions. Very bad.

Re: Declaring C String Constants

#57

Earlier quoted context omitted.

> Why would it be a joke? A certain influential segment of the C and C++ development community, the kind that tends to worship "best practices" and "consistency", has been preaching for years that C preprocessor macros are evil, even in cases where they allow for much clearer code. I'm not sure these people were born with the ability to experience joy.

The biggest problem with C macros is that they are too opaque. The compilation stack will complain about code that is different from what you have, and leave you with little hint about what in your code is generating the broken code. It's also confusing when debugging. That said, yes they can lead to large gains so when they are worth it, go for them. Just mention in the documentation that they are macros, in big let…

> Just mention in the documentation that they are macros, in big letters.

The macros themselves are usually in BIG_LETTERS already... that generally gives it away.

Re: Declaring C String Constants

#58
post #43
post #35

Earlier quoted context omitted.

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).

It's a global variable, it's not on the stack. It's in the data section. $arr is copying the address of "arr", so it must use an immediate move (possibly 64-bit). It could also use RIP-relative with the "lea" (load effective address) instruction. $ptr(%rip) is accessing memory, so it uses RIP-relative addressing with the "mov" instruction.

> It's a global variable, it's not on the stack. It's in the data section.

And because it's a const, it's in the .rodata section... (read-only) Playing too liberally with the data often leads to a SEGV (as it should).

Re: Declaring C String Constants

#59

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. Try -Wstrict-prototypes, then `void` is required.

That works in GCC, but not in Clang. As far as I can tell Clang has no warnings relating to this at all.

Re: Declaring C String Constants

#60
Other comments have already deconstructed much of the article, but I'll add this. The primary factor will be your CPU architecture. Can you put the string in the same cacheline as the code or an adjacent cacheline? If so, awesome. However, if you have a microcontroller with a harvard architecture, such as a cortex M3, it's may be better to put your strings in data memory rather than code memory. The processor can simultaneously load your string and the next instructions via the two memory ports.
Post reply on HN