4
void f();
int main(int argc, char** argv)
{
    if (f)
    {
        // other code
    }
}

With VS2017, the linker complaint about unsolved external symbol, while it works with GCC. According to C99 spec, is it valid? Or it's implementation detail?

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • But that wouldn't compile on gcc if the function didn't exist? It either compiles and is *always* true, or it fails to compile... – Jason Oct 20 '22 at 13:26
  • 1
    https://onlinegdb.com/Dwmxd9U0R – user20291889 Oct 20 '22 at 13:29
  • It's common to check if the weak function is defined(usually user defined callback) in embedded code. – user20291889 Oct 20 '22 at 13:29
  • I think it's the implementation detail in linker, it's not specified in spec AFAIK. But I cannot make sure since the spec is complicated. – mingpepe Oct 20 '22 at 13:33
  • Weak/strong symbols is not something that the C standard concerns itself with, so there isn't an official answer here. It depends on the toolchain you are using. – Marco Bonelli Oct 20 '22 at 13:34
  • I'm not sure how this could compile and _not_ be true... – CoffeeTableEspresso Oct 20 '22 at 13:36
  • 2
    @Jason: Re “But that wouldn't compile on gcc if the function didn't exist?”: `void f();` is a declaration, and it and `if (f)` will compile regardless of whether or not the function exists. Function existence matters during linking, not compilation. – Eric Postpischil Oct 20 '22 at 13:39
  • 1
    I do not expect tagging this with language-lawyer is useful. As far as the C standard, `void f();` declares `f` to be a function, and its use in `if (f)` results in its conversion to a pointer to a function, and that pointer cannot be a null pointer, so the `if` is always true. And that is all you will get from the standard. Weak linking and testing whether functions are actually available is outside of the C standard. – Eric Postpischil Oct 20 '22 at 13:44
  • `It's common to check if the weak function is defined(usually user defined callback) in embedded code.` no it is not. I would even say that is never done. – 0___________ Oct 20 '22 at 13:46
  • @0___________ It may not be *common* but it’s definitely done, and not just in embedded code. In my previous job we had a preload library which was doing similar shenanigans to support different versions of a dynamically linked dependency. By design our product had complete control over the toolchain up to the dynamic linker, so we were able to rely on this mechanism. – Konrad Rudolph Oct 20 '22 at 14:14
  • In GCC you can use `weak` attribute: https://stackoverflow.com/a/6916925/1778275. Demo: https://godbolt.org/z/c1E535W1o. – pmor Oct 25 '22 at 08:37
  • MSVC has undocumented feature `/alternatename` (https://stackoverflow.com/a/11529277/1778275). – pmor Oct 25 '22 at 09:32

3 Answers3

3

C standard requires that every symbol should be defined exactly once in a correct program, but does not require any diagnostic if the rule is not observed. So if you declare a function that is never defined in any compilation unit any use of that function is beyond C specification.

The gcc compiler is known to have plenty of extensions, some of which are also accepted by clang. If you know that you will only use gcc, you can use them, if you want to write portable programs you should not.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
0

GCC regards a declared function as always existent, even with -O0, and therefore optimizes the code to:

#include <stdio.h>

int main(int argc, char** argv)
{
    printf("Y\n");
}

If you add common warning options to the compiler command line, GCC will warn you about this, too.

the busybee
  • 10,755
  • 3
  • 13
  • 30
  • [It’s not that clear-cut.](https://godbolt.org/z/r1aaT44sG) – Konrad Rudolph Oct 20 '22 at 14:06
  • The example is based on the poster's original code, but my answer is incomplete, though. – the busybee Oct 20 '22 at 14:19
  • I'm using the attribute annotation for the sake of Godbolt. IIRC you don't need to change the code to annotate the symbol as weak, you can also define this out of line, via a linker script. – Konrad Rudolph Oct 20 '22 at 14:33
  • If you annotate a symbol as weak in a linker script, the compiler knows nothing about this - and will happily optimize. :-D – the busybee Oct 20 '22 at 14:54
  • I thought I remembered that there was a command line option to tell GCC to accept weak annotations from elsewhere but I can’t find it now. – Konrad Rudolph Oct 20 '22 at 15:04
  • @KonradRudolph I discovered too that `__attribute__((weak))` makes GCC to _not_ optimize `if (f)` to `if (1)`. – pmor Oct 25 '22 at 10:36
-1

It's common to check if the weak function is defined(usually user defined callback) in embedded code.

No, it is never done as it cannot be done. Your code may have some pointers to functions and you can check if those pointers are not NULL (ie have been assigned with some function pointer references, but cant check if those references are correct).

0___________
  • 60,014
  • 4
  • 34
  • 74