On Wed, 2013-12-18 at 01:33 +0000, Steven D'Aprano wrote: > And "What does 'implementation-specific undefined behaviour' actually > mean in practice?", another common question when dealing with C.
Only asked by people who haven't had it explained. There's "undefined behavior", and there's "implementation-specific behavior", but it is impossible to have "implementation-specific undefined behavior". And, the definitions are simple to understand: "undefined behavior" means that if your program invokes it, there is no definition of what will happen. This is buggy code. "Implementation-specific" behavior means that the standard requires the implementation to do some well-defined thing, but the standard does not define exactly what it must be. You can go look up what your implementation will do in its documentation (the standard requires that it be documented), but you can't assume the same thing will happen in another implementation. This is non-portable code. It's a very rare language indeed that has no undefined or implementation-specific behaviors. Python gets to "cheat" by having one reference implementation. Every time you've had to go try something out in the Python interpreter because the documentation didn't provide the details you needed, that WAS implementation-specific behavior. > > You never have to wonder what the > > lifetime of an object is, > > Since C isn't object oriented, the lifetime of objects in C is, um, any > number you like. "The lifetime of objects in <some language with no > objects> is ONE MILLION YEARS!!!" is as good as any other vacuously true > statement. The implication that only an "object oriented" language could have a concept of object lifetimes is false. Another, less hyperbolic way of saying this is that in C, the lifetime of objects is _exactly as long as you specify_. Heap objects come into existence when you explicitly create them, and they go out of existence when you explicitly destroy them. If you don't destroy them, they never go away. If you destroy them more than once, that's undefined behavior. Stack objects are even simpler. > > or be mystified by which of the 7 signatures > > of Foo.foo() are going to get called, > > Is that even possible in C? If Foo is a struct, and Foo.foo a member, I > don't think C has first-class functions and so Foo.foo can't be callable. Of course that's valid C. It's true that C doesn't have first-class functions, but it supports invoking functions through pointers and you can store functions in data members, pass functions as arguments, and return functions from other functions, so Foo.foo can certainly be callable. ~$ cat /tmp/foo.c #include <stdio.h> struct Foo { void (*foo)(); }; void foobar(void) { printf("foobar\n"); } int main() { struct Foo Foo = { foobar }; Foo.foo(); return 0; } $ gcc -Wall -o /tmp/foo /tmp/foo.c $ /tmp/foo foobar -- https://mail.python.org/mailman/listinfo/python-list