The Clang 6.0.1 avxintrin.h has the declaration:
static __inline __m256i __DEFAULT_FN_ATTRS _mm256_set1_epi32(int)
GCC 5.5 has:
extern __inline __m256i __attribute__((__gnu_inline__, _always_inline__, __artificial__)) _mm256_set1_epi32(int)
Why would one be extern and one static? This is showing up for me in an inline function that calls _mm256_set1_epi32. Clang wants it to be declared static:
#include <immintrin.h>
inline void SimdBlockBloomFilter_make_mask() {
_mm256_set1_epi32(1);
}
With -Weverything:
warning: static function '_mm256_set1_epi32' is used in an inline
function with external linkage [-Wstatic-in-inline]
This error does not show up when compiling with Clang++.
In the GCC version, the gnu_inline attribute is close to the behavior of static inline in C99 and later modes.
The C committee ignored the GNU precedent when redefining the meaning of extern inline: With the GNU compiler, extern inline meant that the compiler should never generate a non-inline copy of the function (even if its address is taken). In C99, extern inline means that a definition in a translation unit completes an inline definition in another translation unit.
The GCC version of <immintrin.h> uses the gnu_inline attribute to get the expected behavior in all compiler modes (C89/C90 and C99 in particular).
Related
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
I'm experimenting with inline and external definitions and here are 2 source files linked together:
foo.c:
#include <stdio.h>
void foo(void){
printf("Test external definition\n");
}
main.c:
#include <stdio.h>
inline void foo(void){
printf("Test\n");
}
int main(void){
foo();
}
Compiling an linking 2 files together Test is printed in console.
N2346::6.7.4/p6 provides that:
It is unspecified whether a call to the function uses the inline
definition or the external definition.
and
If all of the file scope declarations for a function in a translation
unit include the inline function specifier without extern , then the
definition in that translation unit is an inline definition. An inline
definition does not provide an external definition for the function,
and does not forbid an external definition in another translation
unit.
So in the example there are inline definition and external definition. And it's unspecified which one is called.
I ran tests and in my case the inline definition was called. Is there a way to force gcc to call external definition? Maybe there is some flag?
Citing from 6.7.4/10:
A file scope declaration with extern creates an external definition.
For the external definition to be available to choose from (however the compiler chooses) there must actually be an extern function declaration.
From the example:
inline double fahr(double t) { ... }
...
extern double fahr(double); // creates an external definition
when i try to include a .h file which consists of definition for inline functions as
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SLA (int32_t o1, int32_t o2, int32_t o3)
it is giving the "warning: always_inline function might not be inlinable [-Wattributes]" can you somebody help me i am struggling to fix it.
For functions declared inline(!!!!), this attribute inlines the function independent of any restrictions that otherwise apply to inlining.
So, when you set the attribute without declaring the function inline you will get these warning. Declare the function additionally inline will void these warnings. Behavior gnu gcc/g++ 5.30
# define FORCE_INLINE __attribute__((always_inline)) inline
FORCE_INLINE vec3 operator- (vec3 a, vec3 b) { vec3 t = { a.x-b.x, a.y-b.y, a.z-b.z }; return t; }
finally, after spending two days efforts found the solution as it is below
it is just because of a compiler(arm-none-eabi-gcc) option in Makefile
CFLAGS= -D inline if this flag is set, it throws warning as __attribute__( ( always_inline ) ) __STATIC_INLINE(inline) uint32_t __SLA (int32_t o1, int32_t o2, int32_t o3) when trying to include a .h file which consists of always inline functions
What that warning is saying is that the compiler, is not always happy accepting your function as inline, or it wants it to be declared as inline.
I guess it's that __attribute__ ((always_inline)) implies inline - in which case the parsing of the attribute needs to set DECL_DECLARED_INLINE_P.
The GCC manual specifies
always_inline Generally, functions are not inlined unless optimization is specified. For functions declared inline, this attribute inlines the function even if no optimization level is specified.
Here's the gcc test for the revision
__attribute__ ((always_inline)) does not imply "inline" in gcc. If you use __attribute__ ((always_inline)) without also using "inline" then you will see this gcc warning message, unless it is disabled:
warning: 'always_inline' function might not be inlinable
In the original post I suspect that __STATIC_INLINE(inline) is intended to expand to static inline.
There may be other reasons why the function cannot be inlined, for example if it is recursive.
Doing cc -std=c99 example.c on the following simplified example.c file:
inline void a()
{
}
int main()
{
a();
return 0;
}
gets me:
In function `main':
example.c:(.text+0x7): undefined reference to 'a'
collect2: ld returned 1 exit status
As I understand this has to do with the requirement of C99 standard to demand exactly one more definition for each inline non-static function that is used in cases where the body cannot be inlined? If that is so, I am guessing I could do with static inline instead, but I don't want this to bite me later, so what would be the best course of action here? Obviously, I want to stick to C99 and I want to inline some functions. (Yes, I am aware the compiler usually knows what to inline without being told so, but I have my reasons)
Probably you wouldn't have that error when you compile with -O2 or so.
Inline function definitions should go in header files and an extern inline declaration should go in one compilation unit. Do
inline void a(void){
// empty
}
// in just one .c file
#include "the-file.h"
extern inline void a(void);
BTW, declaring a without void is not a prototype.
There's no function prototype, that's all, so the function signature is inferred, and inferred wrong. Add "void a();" to the top of the file, and you're all set.
I'm writing a library in C99, and there are some parts of the library that would benefit significantly from the use of a macro / inline function. Inline functions are a better fit for my library.
However, very specifically I do not want to externally expose these inline functions.
Everything appears to work, but when I link against the library to create an executable I get the error: "undefined reference to `na_impl_gfx__draw'"
I have reproduced the problem to a minimal test case which does exactly what I do:
lib.h:
void somefunc();
lib.c:
#include <stdio.h>
#include "lib.h"
inline void someinline(char *value);
void somefunc() {
someinline("Hi!");
}
inline void someinline(char *value) {
printf("%s\n", value);
}
main.c:
#include "lib.h"
int main(int argc, char *argv[]) {
somefunc();
}
Now we compile:
doug#Wulf:~/test$ gcc -c -std=c99 lib.c
doug#Wulf:~/test$ gcc -c -std=c99 main.c
doug#Wulf:~/test$ gcc -std=c99 lib.o main.o
lib.o: In function `somefunc':
lib.c:(.text+0xe): undefined reference to `someinline'
lib.c:(.text+0x1a): undefined reference to `someinline'
lib.c:(.text+0x26): undefined reference to `someinline'
collect2: ld returned 1 exit status
It would appear that when compiling the library, the inline function is not being substituted into the object code for the function somefunc() in lib.h
Why?
The inline function is not externally visible. I would expect that when the library is compiled, the inline function is inlined into the function, just like the macro is (Nb. using only a macro this code compiles file).
What am I doing wrong? Or is this a restriction of inline functions?
The reason that you can't see the inline function in the same source file is that you haven't made them static.
All you need to do is make the prototype static with:
inline static void someinline(char *value);
and the function definition static with:
inline static void someinline(char *value) {
printf("%s\n", value);
}
[Sorry for kicking in as lately, you should have tagged your question with C and not only C99.]
I think with your question you are completely on the wrong track. Inline functions only make sense when you put them in a ".h" file. The whole concept is about making the function definition visible to all callers.
If you'd do so you should just put the definition (with the inline) in the header and an external declaration (with extern inline) in one compilation unit.
If you just want to have functions put in place in your "lib.o" compilation unit, forget about all that inline or static and let the compiler do that for you. gcc does that if you switch on optimization:
`-finline-small-functions'
Integrate functions into their callers when their body is smaller
than expected function call code (so overall size of program gets
smaller). The compiler heuristically decides which functions
are
simple enough to be worth integrating in this way.
Enabled at level `-O2'.
// common.h
// This is foo function. It has a body.
__inline void foo() { /* something */ }
// a.cpp
#include "common.h" // for foo function
// Call foo
// b.cpp
#include "common.h" // for foo function
// Call foo
I would like to inline the foo function only when I build for release. I don't want to inline functions for Debug build.
I tried it but linker errors annoyed me.
In this case, foo function's body is defined in common.h header file.
so if I just do
//common.h
#if !defined(_DEBUG)
__inline
#endif
void foo() { /* something */ }
It will be met a link error in DEBUG build. Because two modules try to include common.h.
I have no idea to solve it.
Is it possible?
The "easy" solution would be this:
#if !defined(_DEBUG) || defined(NDEBUG)
#define INLINE inline
#else
#define INLINE static
#endif
static is necessary to silence linking errors and get around the One Definition Rule.
A better solution would be to simply disable inlining project wide for debugging. GCC supports the -wno-inline-functions and -fno-inline-small-functions options to counteract those optimizations, and it also does not enable inlining for -O1 or lower (and probably -Os as well). Most compilers have similar options.
I call the latter a better solution because it should instruct the compiler to ignore the inline hint, eliminating the need for pesky preprocessor directives.
The fundamental thing to realize is that the inline keyword (or Microsoft's __inline extension for C - since MSVC doesn't support C99) is essentially a pass to violate the one definition rule. If you think about it - that's all it really is, since the compiler is under no obligation to actually perform any inlining.
So, when you have an inline function you're allowed to have the function defined in more than one module. In fact, you're obligated to have it defined in any module that actually uses the function.
However, if you don't declare the function as inline, you have to ensure that you have no more than one definition (exactly one if it actually gets used). For non-member functions (all function in C), there are a few ways around this:
declare the function as static to change it's linkage to internal (note that you can have static inline functions to begin with).
in C++ you can place them in an anonymous namespace (which has an effect similar to declaring the static)
you can use preprocessor manipulation to handle this. It's kind of ugly, but it works, and I've seen the technique used successfully in the wild. Whether it's worth the effort is another thing altogether - you'll have to decide that yourself.
Basically, what you need to do is have an implementation of the function in a separate .c file, just like if you were following the tradition of a-single-function-per-module coding standard (actually you can do this just as well putting several inline functions in the .c module - but they should all be inline or not inline as a group to keep things from getting too out of hand). The implementation of the function needs to arrange to be able to be included in a header - so it needs include guards, just like any other header. Then you use the preprocessor to conditionally include the implementation as part of the header when you want inline functions (so the implementation will be available to all modules), but don't include it if you're not inlining (so you follow the one definition rule in that case):
The common.h header:
// common.h
#ifndef COMMON_H
#define COMMON_H
#ifdef RELEASE
#define USE_INLINE
#define INLINE __inline
#else
#define INLINE
#endif
INLINE void foo(void);
#ifdef USE_INLINE
#include "foo.c"
#endif
#endif /* COMMON_H */
The implementation of foo():
// foo.c
#ifndef FOO_C
#define FOO_C
#include <stdio.h>
#include "common.h"
INLINE void foo()
{
printf("foo\n");
}
#endif /* FOO_C */
And an example program:
// main.c
#include<stdio.h>
#include "common.h"
int main()
{
foo();
return 0;
}
Now if you compile for release:
cl /DRELEASE main.c foo.c
foo() will be inline (or __inline as the case may be).
If you compile for non-release:
cl test.c foo.c
you have a non-inline foo().
And both the compiler and linker are happy in either case.
All that said, I kind of like the suggestion to maybe redefine INLINE to be static for debugging purposes.
However, ultimately I'm not sure I see the point to any of this really - modern debuggers are able to step through functions that are inline, and the debugger probably won't inline function calls if you disable optimizations. So you can set breakpoints inside the inline function as well and have it work fine in non-optimized builds.
I'm not sure exactly what you're end-goal in this really is. What's the drawback to leaving the functions as inline in debug/non-optimized builds?
#ifdef RELEASE
#define INLINE __inline
#else
#define INLINE
#endif
Then
// common.h
INLINE void foo() { /* something */ }
// a.cpp
#include "common.h" // for foo function
// Call foo
// b.cpp
#include "common.h" // for foo function
// Call foo
then define RELEASE for the release version. of course you can see from this there are lots of ways to do it.
You can't declare header only functions as non-inline. You could declare them as static (a.k.a. C-style static), but that will generate a copy of the function (including local static variables, if any) in each translation unit. A better solution is to leave it as inline. In debug mode when optimizations are disabled compilers usually don't inline any functions.
In most cases release flags are not defined. Typically debug flags are defined.
_DEBUG is defined by most compilers, so there is no need to define a release flag:
More practical:
#ifndef _DEBUG
__inline void foo() { /* something */ }
#else
//some alternative
#endif
Use compiler conditionals and define a compile time flag.
Example:
#ifdef RELEASE_BUILD_FLAG
//Run inline function
#else
//some alternative
#endif