Post funny code/snippets you came across

eternal_noob Yep that should be the defaults in my opinion. It's ironic how many "weird little bugs" are actually fixed if you pay attention and correct compiler warnings.
Been a while since I looked but I think C++ treats int foo() like int foo(...) as Crivens points out. That may be relaxed or tightened in some versions of C++, I just don't recall any more.
No that's backwards.

K&R C was pretty lax and kind of assumed that hardware == VAX. Function declarations were not required and arguments would be promoted to int or double (there was certainly no long long back then, I'm not sure about long). Such implicit function declarations were assumed to have an int return type. In the time-honoured C programming tradition, this would then use the technique of "cross your fingers and hope that it works". If you were lucky the function call would actually match the function definition and not crash. Sophisticated K&R C programmers would declare their functions like "void * foo()". This at least means that the compiler now no longer has to guess the return type. It still means "any number and any type of arguments". That means argument matching still relies on crossed fingers.

ANSI C slightly upped the ante with function prototypes. That declares the function name return type _and the number and types of the arguments_. Coo! But you're still not entirely out of the woods. If by some error you have different prototypes seen by the definition and function call you will get no compiler or link error. That's because the object file symbol will be just "foo" without any information on the arguments. In this case you still need to cross your fingers at runtime.

C++ has always been much stricter.

There has never been any of this implicit declaration nonsense. There has never been any of this declaration/prototype nonsense. In C++ all types need to be declared before they are used. Including functions.

In C++ "void* foo()" means a function taking no arguments.

Linking in C++ is also safer than in C. C++ uses name mangling. That means that when compiling "void *foo()" the compiler will emit _Z3foov as the name. That will only link with a foo without any arguments.

Unfortunately even C++ requires a small amount of finger crossing. As far as I'm aware object file formats (ELF for unix-like, COFF for Windows and macho for macOS) are all fairly rudimentary and, as a consequence, so are link editors. Some things have been done to bodge object files to handle more needs (mangled names, mutliple text sections like .text._Z3fooIciEPT_T0_ for templates/inlined functions). But even still the link editor does not know about C++ function _return types_. (Maybe because of the difficulties in handling covariant return types).

If you want to detect these kinds of errors before your application crashes, you need to use a static analysis tool (clang-tidy, coverity etc) that can do whole program analysis.

Finally, all of this nonsense would probably not have been necessary in the first place if C didn't have promotions and implicit conversions. Most non-C-based languages that I know (and that's not a lot) do not need to include headers.
 
In C++ all types need to be declared before they are used. Including functions.
Oh, and one more barrel to shoot your own foot with - they need to be equal in NAME. Then the compiler is satisfied and the linker also.

A little tale from the crypt: Once upon a time I spent some days writing a lint tool for object files/libs that went trough the debug information and made sure that these definitions came from the same place and were equal. That was after 4 man-weeks of searching an obscure heisenbug. Turns out the search order of includes was involved, and some cool guy had an #ifdef in a class definition that was not set for all components equally.
That is why I like things like Oberon these days. Binary module concept, hashes included, checked by the linker/loader if the build is consistent.
 
In Late 2021 i upgraded my Linux-Box to Kernel 5.14, and promptly the Backlight didn't work anymore --> Dark Screen
On another Forum i got some help from a guy, who even checked the Source-code, and he found this comment
C:
/*
     * If the driver is probed from the device tree and there is a
     * phandle link pointing to the backlight node, it is safe to
     * assume that another driver will enable the backlight at the
     * appropriate time. Therefore, if it is disabled, keep it so.
     */

it's safe to assume????????? 😂
Must have been a former Microsoft-Employee......😂😂😂
 
Oh, and one more barrel to shoot your own foot with - they need to be equal in NAME. Then the compiler is satisfied and the linker also.

A little tale from the crypt: Once upon a time I spent some days writing a lint tool for object files/libs that went trough the debug information and made sure that these definitions came from the same place and were equal. That was after 4 man-weeks of searching an obscure heisenbug. Turns out the search order of includes was involved, and some cool guy had an #ifdef in a class definition that was not set for all components equally.
That is why I like things like Oberon these days. Binary module concept, hashes included, checked by the linker/loader if the build is consistent.

Can't give enough thumbs up for Oberon. I used to play with it a long time ago. Really nice and simple, super fast build times. OS with GUI and compiler would fit on a 3.5" floppy. Here's what I had to say about it back in 1998 from an OS/2 user's perspective http://www.edm2.com/0608/oberon.html

Out of curiosity, which Oberon compiler do you use?

And yes, ODR violations with data structures are bad news. The link editor knows nothing about them. Your global and static data objects just have a name and a size. Local variables and function arguments other than the type name are only seen by the compiler. I also experienced something similar early in my career where we had two headers with different definitions of the same struct name.
 
Yes. One case of perl-based build system was sorting the include path set for the project. One guy named his project folder "project", the other one "Project". Guess what happend? One could build, the other not, even while the content of the build was equal bit for bit. Swear words were shouted.
 
Out of curiosity, which Oberon compiler do you use?
I started that on the good 'ol Amiga. But then C++ came around, and I went that way. Later, I had an old laptop run the 386 version of Oberon2, but you could not do much with that. No way to get files around, flat directory, ... These days I use Lazarus for things that need a GUI and like that I can build the same thing on Windows, Linux, FreeBSD, Raspi, ...
And the possibility to have even templates or inlines in a binary module, how cool is that? Do you know a good open source compiler? I'd like to try.
 
hash indicates preprocessor "thing", think #include, #ifdef etc. I'd guess that unknown characters after a hash simply produce nothing, no preprocessor expansion.

Easy way to figure out what could happen is create the standard "hello world" program in c, add that as the last line, the compile it.
 
Alain De Vos If I read that code of yours correctly, you can add fields to a class definition from a method? The children part? Or is that a bug?
The class <male> is a subclass of <human> and inherits a field "children"
When <male> sends the method "have-sex!" with parameter <female> the element "newborn" is prepended to the list of "children".
 
I started that on the good 'ol Amiga. But then C++ came around, and I went that way. Later, I had an old laptop run the 386 version of Oberon2, but you could not do much with that. No way to get files around, flat directory, ... These days I use Lazarus for things that need a GUI and like that I can build the same thing on Windows, Linux, FreeBSD, Raspi, ...
And the possibility to have even templates or inlines in a binary module, how cool is that? Do you know a good open source compiler? I'd like to try.
It's too long ago now. Maybe when I retire I'll dabble again.
 
Back
Top