February 2023

S M T W T F S
   1234
567891011
12131415161718
19202122232425
262728    

Page Summary

Style Credit

Expand Cut Tags

No cut tags
Thursday, November 29th, 2007 12:07 pm
For the C/C++ geeks out there, here's a grumpymaking thing I stumbled upon today.

In a .h file:
void __inline FUNCTION_NAME(mystruct* foo)
{
   foo->addrValid = TRUE; 
}

And therefore, in my .c file:
// HORRIBLE HACK!  Only one .o in an executable can have StupidInclude.h included.
// It defines inline functions and the link step will fail if multiple .o files
// contain those definitions.  But every .o in this type of executable must have the
// app data structure definition... which, for this app, relies on StupidInclude.h.
// Therefore, there can be only one .o in this executable.
#include "echoer.c"
#include "listener.c"
#include "pinger.c"

I know there are ways around this, potentially involving (say) precompiled headers, but this is supposedly a simple proof-of-concept app so I'm not bothering for now. And seriously. Who would release something like that and not get fired? Never mind; I know the answer.
Thursday, November 29th, 2007 08:33 pm (UTC)
Wait; that doesn't seem to make sense. If the functions are actually inlined, why should this actually fail? The .o file should have that code inlined (which means that the function body must be in the .h file, not in a corresponding .c file, so the compiler can have it when it's making the .o file), and it shouldn't end up defining a symbol for it, so multiple .o files shouldn't conflict.

I think your compiler is on the list of things being idiots. It shouldn't be defining symbols in the .o files for the inline functions, and this ought to work right.

Of course, it's possible that I'm completely off-base here. Or that the problem is that the __inline syntax doesn't do what it's supposed to do because of being the wrong thing for this particular compiler.
Thursday, November 29th, 2007 08:47 pm (UTC)
OK, I'll have to think about that one.

I should mention that almost every developer using this .h file will also be using the compiler I'm using. (For the system I'm trying to work with, there are only two compilers that will work at all, and the other one costs over $1000.) The guys who wrote that .h obviously didn't try it out with multiple object files.
Thursday, November 29th, 2007 09:07 pm (UTC)
It's also possible that this is related to the inline weirdness in GCC (if that's the "doesn't cost over $1000" compiler). GCC defined the __inline keyword before C99 standardized "inline", and the semantics are subtly different (and, iirc, though my recollection is very hazy, this is one of the places where that's true), and I think that the more recent versions of GCC have changed the definition to match the C99 standard.

If that's true, there are compiler flags to use the "other" behavior which may be relevant. It is also possible that a "#define __inline SOMETHING" hack before including the relevant header files will make things work.

Oh, wait a minute. Right. I decided to check and see how we handle this in our libraries, and realized that this is a stupidity on the part of those library developers -- for this to work right, that function needs to be declared static as well as __inline. A rough hunch is that "#define __inline static __inline" will do the right thing, though that's an ugly hack that breaks if __inline is already a preprocessor macro. (Then you'd need "#define old_inline __inline; #undef __inline; #define __inline static old_inline" or somesuch atrocity.)

IMO, if you've got any kind of support at all for this library, I'd send them a "WTF?" email. :)
Thursday, November 29th, 2007 09:15 pm (UTC)
Ohhhhh yes: static __inline would be great. It's what I had hoped to see when I looked in that .h file (that, or macros).

I'm using gcc, yep. Got it in one. :-)
Thursday, November 29th, 2007 09:46 pm (UTC)
Hah -- I was right about this being related to the GCC/inline weirdness, I think. See this post for a review of the issues.

In C99, "inline" means, roughly, the same thing as "static inline". However, GCC still defaults to using the pre-C99 meaning, where it's only a compiler hint with no actual semantic meaning (and so externally-visible symbols should still get emitted).

Passing the -std=gnu99 option to GCC, if you're using a sufficiently recent version, should do the trick (though it may cause other problems).

(I will note that this is all predicated on GCC treating "inline" and "__inline" as identical, which I think is the case, but I'm not absolutely certain of it.)
Friday, November 30th, 2007 06:18 am (UTC)
Cool! Thanks for the link.

It would be spectacularly awful if "-std=gnu99" were incompatible with this system. I wouldn't put it past 'em. But I haven't tried it yet. Other things ate my afternoon. :)