Undefined behaviour
Undefined behaviour
Posted Sep 4, 2018 11:14 UTC (Tue) by excors (subscriber, #95769)In reply to: Undefined behaviour by rweikusat2
Parent article: C considered dangerous
(Incidentally, I've found void pointer arithmetic convenient for things like "void create_packet(void *buf, Header *hdr, void *payload, size_t len) { memcpy(buf, hdr, sizeof(Header)); memcpy(buf + sizeof(Header), payload, len); }", since void* seems the appropriate type for buffers that don't correspond to a specific C type, and sometimes you want to refer to byte offsets within those buffers. Explicitly casting to char* every time you do arithmetic is ugly and semantically inappropriate.)
Posted Sep 4, 2018 12:35 UTC (Tue)
by farnz (subscriber, #17727)
[Link] (5 responses)
The problem with defining behaviour in terms of "this specific implementation does this" is that absent some form of promise from the implementers (either because they promise to comply with a standard that does what you want, or because they document the behaviour you want as deliberate), you can't distinguish "this behaviour is a consequence of a compiler bug that will be fixed removing the desired behaviour" from "this is desirable behaviour that the implementers will try to keep" from "the implementers will treat the absence of this behaviour as a bug and fix it".
This is especially true of behaviour that comes from interacting bugs - it may be true that with GCC 6.7.9.1 on an Intel Xeon E3-1285 v3 with a fixed microcode version and C code compiled with -march=haswell -O3 you get a behaviour you want, but if that's not promised and a microcode update breaks things, you're stuffed.
Hence the interest in what is defined in documentation - yes, I can validate a given implementation's behaviour for a given machine if I so desire, but what I'm normally interested in is "if I upgrade my machine and/or compiler, will my code continue to do what I want?". Nasal demons is simply a short cut for "even though you could validate behaviour, because no-one is trying to maintain this behaviour in future, you don't want to depend on it."
Posted Sep 4, 2018 20:08 UTC (Tue)
by rweikusat2 (subscriber, #117920)
[Link] (4 responses)
"Nasal daemon" and other such nonsense is just the appeal to ignorance I wrote about, though: Behaviour which isn't defined by ISO-C is not a defined phenomenon properties like "you don't want to depend on it" can be assigned to for some rational reason. Eg, the only I/O facilities defined by ISO-C are stdio-streams and no behaviour is defined for the case when data written by the stdio of one C implementation is later read via the stdio of a different implemention. It follows that the behaviour of a program compiled with clang is undefined whenever it tries to read data written by a program compiled with gcc. Surely, clang is something nobody would ever want to depend on!
Posted Sep 4, 2018 20:38 UTC (Tue)
by farnz (subscriber, #17727)
[Link] (3 responses)
"Nasal demon" is just a short-cut to saying that "the behaviour of a program is not defined by the standards you are relying upon to define the progam's meaning, and thus anything could go". This isn't just the ISO C standard, but also POSIX, and even implementation defined standards; in the cases you're talking about, "nasal demons" is a distraction, as there are standards that define the behaviour in question, even if ISO C permits a wider variety of standards-compliant behaviour.
Further, "undefined" behaviour in the sense that "nasal demons" refers to is more than just behaviour where the implementation defines it - it's behaviour where the implementation is allowed to refuse to define what it means. E.g. int i = 0; ++i++ += i++ + ++i; is a common example of undefined behaviour - because it breaks the rules on sequence points, the implementation does not have to give it any meaning at all.
Posted Sep 4, 2018 21:17 UTC (Tue)
by rweikusat2 (subscriber, #117920)
[Link] (2 responses)
As I already wrote: "It is unknown, hence ..." is logically invalid.
Posted Sep 5, 2018 8:45 UTC (Wed)
by farnz (subscriber, #17727)
[Link] (1 responses)
Exactly, but that sort of reasoning about a standard is common - e.g. "The POSIX standard says that int must be at least 32 bits in size, therefore I can assume that long is 64 bits in size". The point of "nasal demons" is that it is equally correct to say "The POSIX standard says that int must be at least 32 bits in siz, therefore assuming long is 64 bits in size will make demons fly out of your nose" - both are logically invalid statements, but while the first sounds plausible, the second does not.
In other words, it's a way of pointing out that your conclusion does not follow from your antecedents in a comical fashion, and thus that you need to go back and fill in your chain of reasoning.
Posted Sep 6, 2018 10:17 UTC (Thu)
by Wol (subscriber, #4433)
[Link]
Cheers,
Undefined behaviour
Undefined behaviour
Undefined behaviour
Undefined behaviour
Undefined behaviour
Undefined behaviour
Wol
