Live data from Hacker News

Declaring C String Constants

eklitzke.org

71–80 of 87 posts

Re: Declaring C String Constants

#71

Earlier quoted context omitted.

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.

> 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. Do you hate C? You clearly like software written in it, ie Debian. > Yes, as I said, for legacy reasons. Starting a new software project wether it be embedded programing or programing on big X86-64 machines is not legacy software.

Yes I hate C.

> You clearly like software written in it, ie Debian.

Yes, but not because it's written in C, but because of its functionality, which can of course be implemented in other languages.

> Starting a new software project wether it be embedded programing or programing on big X86-64 machines is not legacy software.

The problem is why you should start a new software project, which uses C. Most used reason probably is, that C is the standard, there exists only a toolchain for C and other legacy reasons.

Re: Declaring C String Constants

#72
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…

AFAICT, "undefined behavior" refers to two entirely-separate classes of behavior:

1. cases where the compiler explicitly recognizes a certain permutation of compilation-state as matching some pattern for what the standard calls "undefined behavior"—and then is unconstrained as to what it does in response, but indeed does something in response to detecting that state;

2. cases where the compiler has no compile-time static-analysis approach available for detecting a certain edge-case (e.g. integer overflow), and, further, is inhibited by the standard from generating code to detect that edge-case at runtime either; so the compiler is forced to leave the response to that condition either up to the programmer to explicitly handle, or up to the target architecture to respond to however it likes when it happens.

It's clear to me that undefined behavior of the second class is sort of just part of what C "is": a language where the complexity-classes of all the primitives [well, except FP math] are constrained at compile-time, so a line of code that's O(1) on one arch won't get runtime-polyfilled into being O(N) on another in order to "make the arch sane."

But my question, then, is this: would it break anything about support for the "not C machine" architectures, if the standard said that everything falling into the first class—explicit undefined behavior—was instead defined behavior, defined as "abort compilation"?

Re: Declaring C String Constants

#73
post #72
post #51

Earlier quoted context omitted.

> 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…

AFAICT, "undefined behavior" refers to two entirely-separate classes of behavior: 1. cases where the compiler explicitly recognizes a certain permutation of compilation-state as matching some pattern for what the standard calls "undefined behavior"—and then is unconstrained as to what it does in response, but indeed does something in response to detecting that state; 2. cases where the compiler has no compile-time st…

I don't know, but I would dearly love to use a compiler that does that.

Re: Declaring C String Constants

#74
post #69

Earlier quoted context omitted.

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. Clan…

I think it is not included in -Wall because such prototype are legitimate pre-ANSI K&R C function prototypes.

Hmm, could be! Maybe explicitly specifying a newer standard might do the trick then. I'll try a few things.

Re: Declaring C String Constants

#75
post #72

Earlier quoted context omitted.

AFAICT, "undefined behavior" refers to two entirely-separate classes of behavior: 1. cases where the compiler explicitly recognizes a certain permutation of compilation-state as matching some pattern for what the standard calls "undefined behavior"—and then is unconstrained as to what it does in response, but indeed does something in response to detecting that state; 2. cases where the compiler has no compile-time st…

I don't know, but I would dearly love to use a compiler that does that.

> I don't know, but I would dearly love to use a compiler that does that.

Well you're in luck, since gcc -Werror when used with many of its -W flags will do precisely that.

You guys should read the minutes of committee discussions and position papers. "undefined behavior" is not something introduced to make programmers' lives hard!

Also look at IEEE734 which does define things to an incredible degree -- it's extremely hard to use (as it needed to be!). It's one of the very best standards of all time, and still has, yes, undefined behavior.

Re: Declaring C String Constants

#76
post #75

Earlier quoted context omitted.

I don't know, but I would dearly love to use a compiler that does that.

> I don't know, but I would dearly love to use a compiler that does that. Well you're in luck, since gcc -Werror when used with many of its -W flags will do precisely that. You guys should read the minutes of committee discussions and position papers. "undefined behavior" is not something introduced to make programmers' lives hard! Also look at IEEE734 which does define things to an incredible degree -- it's extremel…

> Well you're in luck, since gcc -Werror when used with many of its -W flags will do precisely that.

That's not lucky; I'd argue it's the opposite. An ecosystem built around compilers that default to not using -Werror (or rather: `-Werror=pedantic -pedantic-errors`) is an ecosystem that encourages people to write code that relies on the optimizations compilers make in response to undefined behavior. Which, undoubtedly, "makes [maintenance] programmers' lives hard," when they change one little thing and suddenly the code gets 10x slower because now e.g. a dead loop isn't being elided.

If all compilers defaulted to something like `-Werror=pedantic -pedantic-errors`—and it was highly discouraged to turn those flags off—then jumping in to contribute to a portable, sprawling codebase would be infinitely simpler, because the codebase would have been written in a far more rigorous way up to that point.

Sunlight is the best disinfectant—so why do we allow our compiler-vendors to default the lights to off?

Re: Declaring C String Constants

#77
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?

It's not variadic, it's unspecified arguments. The compiler ought to complain if two function calls are made with conflicting argument types.

Re: Declaring C String Constants

#78

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…

BTW -Wall doesn't give you all warnings. It gives you a specific set, which will never change because of all the legacy codebases using -Wall that Clang doesn't want to cause problems with when introducing new diagnostics. The flag that really gets you all of the diagnostics is -Weverything.

Re: Declaring C String Constants

#79
post #68
post #62

Earlier quoted context omitted.

This is a little off topic, but does anyone have any good resources to help me wrap my head around pointers in C? Right now they are very confusing to me.

Imagine all memory is a big array. A pointer is just an index into that array. A pointer dereference is like accessing something at an array index. A pointer to a pointer is array index to a location where you'll find another array index.

I understand pointers conceptually. It's the syntax (in C specifically) that is giving me trouble. I am fine with pointers in ASM.

Re: Declaring C String Constants

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

The code is more interesting if you -do- actually dereference the pointer, too. I've changed the prototype of "bogus" to take a single char as the first argument, and dereference the two pointers inside the do_arr/do_ptr functions:

https://goo.gl/jZYx0f

So the "do_arr" version "knows" what value is at * arr because "arr" is immutable, so the compiler can just choose to load a constant. The "do_ptr" version has to load from memory instead.

But what if we tell the compiler that the value of "ptr" won't change (i.e. "char * const" instead of "const char * ")? The code becomes the same:

https://goo.gl/iNaUHe

So basically "const char []" and "char * const" are more logically equivalent here.

Post reply on HN