Hacker News new | ask | show | jobs
by cornstalks 881 days ago
The C standard does not allow it. It’s simply undefined behavior under the standard, and all bets are off as far as C is concerned.

But of course an implementation is free to define additional behaviors beyond the C specification. That’s done all the time. But that’s really a “flavor” of C and not pure “vanilla” C.

1 comments

No, it's implementation-defined, not undefined behavior. That means the compiler must document a consistent behaviour. From 6.3.2.3 [ISO/IEC 9899:2011]:

An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.

Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.

Also, the C standard merely codified existing practices and common extensions. Actual use of C has converted integers to pointers for a long time. If converting integer literals into pointers were undefined behavior, it would just show that the C standard isn't being practically useful in one area (since it's commonly done in practice).

> Actual use of C has converted integers to pointers for a long time.

Quite probably since the first C-based implementation of Unix on a PDP-11. So it's been known to be "a thing that C does" for quite a bit longer than the standard existed.

If you want your program to work on more than one architecture+compiler combination, then implementation-defined is effectively the same as undefined.
Not entirely.

Say I'm doing my original example, working on an embedded system. My code isn't going to port to anything that doesn't have the same hardware, so architecture isn't an issue. Any compiler supporting that architecture for an embedded application is going to do the right thing with that kind of C statement, so that isn't an issue either.

So, implementation-defined means that you can't count on compilers doing the same thing. But there are some things that are implementation-defined where you can pretty much count on any compiler doing the same thing. And, as trealira said, compilers are supposed to clearly state what they do in such cases, so you can read the compiler's statement and see if there are any surprises.

This is less true if you're writing library code. There, you have to support all compilers, or at least all conforming ones, and you have to make fewer assumptions.