1

divide.h

#pragma once

#include <assert.h>

inline int divide(int a, int b)
{
        assert(b != 0);
        return a / b;
}

main.c

#include <divide.h>

int main(void)
{
        divide(10, 2);
        return 0;
}

I am unable to compile the following solely because of the assert. If I remove the assert, everything works fine.

$ gcc --version
gcc (GCC) 8.1.0
$ gcc main.c
main.c:(.text+0xf): undefined reference to `divide'
$ gcc main.c -O3 # Compilation with optimization works as asserts are removed.

When placing the defintion of divide inside a .c file, everything works fine. However, shouldn't the following also work since the function is declared as inline?

  • Why do you have executable code in a header file? The compiler is not *obliged* to make the function inline - this is not a macro. – Weather Vane May 19 '18 at 19:45
  • @WeatherVane You can't really make an `inline` function includable without it residing entirely in a header file though, can you? – Siguza May 19 '18 at 19:47
  • 1
    @JohnBoyer if you want to _force_ the compiler to use the inline function, you'll want to declare it `static inline`. – Siguza May 19 '18 at 19:48
  • 1
    Please read [small functions defined in header files: inline or static?](https://stackoverflow.com/questions/9428433/small-functions-defined-in-header-files-inline-or-static) – Weather Vane May 19 '18 at 19:49
  • Funny thing from testing, when you remove the inline identifier from the function, the code compiles perfectly. Also, the compiler should just place the text in the header file where it is `#included`, so executable code in the header should be fine to the compiler, (I don't recommend it myself). – OrdoFlammae May 19 '18 at 19:52
  • gcc 8 defaults to `-std=gnu11` which uses the ISO C inline behaviour . It is only `gnu89` standard that gets the "gcc inline" semantics discussed in the linked questions – M.M Nov 18 '20 at 19:08

1 Answers1

1

The C99 standard says this about inline functions in 6.7.4 "Function specifiers":

An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition.

So an implementation can choose to not inline a function call in which case there needs to be an external definition of the function. I'd guess that since the assert is a debugging tool, GCC doesn't want to inline functions that have active asserts to aid in debugging.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760