Inline Function Code Doesn't Compile

inline function code doesn't compile

As hinted at in the question, you need to add two directories to the Windows PATH environment variable:

  1. The Rtools executable directory, probably in C:\Rtools\bin.

  2. The gcc executable directory, probably in C:\Rtools\gcc-4.6.3\bin.

You'll likely need to reboot Windows in order for R to be able to see the new PATH.

You can add update the path environment variable for the current R session only, using something like:

rtools <- "C:\\Rtools\\bin"
gcc <- "C:\\Rtools\\gcc-4.6.3\\bin"
path <- strsplit(Sys.getenv("PATH"), ";")[[1]]
new_path <- c(rtools, gcc, path)
new_path <- new_path[!duplicated(tolower(new_path))]
Sys.setenv(PATH = paste(new_path, collapse = ";"))

Why does inlining my accessors break my code?

I am not a language lawyer, so I can't tell if the compiler behaviour is legitimate or not. Yet, I can explain what is happening.

When you are marking your functions inline, you are not hinting the compiler that it can inline this function. Since over 10 years compilers do not need your hint here. They know when to inline. Instead, what you do, you indicate the function definition to be local for every translation unit it is included in. For this definition should be available.

Effectively what you said is that name() definition should be local for every .cpp file, but you didn't make it available for every .cpp file! I still believe the compiler could give a warning here.

can compiler deciding not to inline a function lead to multiple definitions?

In short: Any "optimization decisions" made by the compiler during compilation will never lead to a compile error. So the answer is NO.

C: undefined reference to inline function

You can add the static keyword before every inline function.

By doing that you force the linker to include the function symbol in the symbol table:

static inline void *Get_Opt_FileHeader_POS(void **p_filebuffer);

Another option is to simply remove the inline keyword.

What does compiler really do when a class inline function is called?

An optimizing compiler can inline as it wishes.

For example, you might compile and link an entire program with g++ -flto -O2 (link-time whole program optimization option of GCC...).

(caveat: using g++ -flto -O2 would slow down significantly your build process; basically everything is compiled nearly "twice", once at "compile" time, once at "link" time, where GIMPLE representation gets re-optimized)

You'll be surprised by what function calls get inlined (a lot of them could be). It is unrelated to static or not functions marked or not as inline.

So you should not care about inlining (it is an implementation and optimization detail), but you hope that the compiler will do a good job.

(sometimes with g++ you want to disable most inlining to ease debugging with gdb; then compile with g++ -fno-inline -Wall -Wextra -O0 -g)

So these inline functions will not be replaced by compiler when they are called outside the class, am I right?

You are wrong, this is just an implicit argument (see also that), and of course compilers are often inlining calls to member functions. In practice C++ would be inefficient if compilers did not that optimization (since many member functions -e.g. getters and setters- are quite short and quick).

Remember that C++ is a specification written in some report (it is not a compiler). Inlining is a quality of implementation issue, and may or not happen.

If you care about what do the compiler really does (and you should not care, but you need to avoid undefined behavior in your code), ask it to show the generated assembler code. With GCC compile with g++ -O2 -fverbose-asm -S to get a foo.s assembler file from a foo.cc translation unit.

gcc fails to inline functions without -O2

Adding the "-O" option to your compiler command. Inlining is turned on only when optimization is enabled.

C99 inline functions

By default, Clang builds C code in GNU C11 mode, so it uses standard C99 semantics for the inline keyword. These semantics are different from those in GNU C89 mode, which is the default mode in versions of GCC prior to 5.0. For example, consider the following code:

inline int add(int i, int j) { return i + j; }

int main() {
int i = add(4, 5);
return i;
}

In C99, inline means that a function's definition is provided only for inlining, and that there is another definition (without inline) somewhere else in the program. That means that this program is incomplete, because if add isn't inlined (for example, when compiling without optimization), then main will have an unresolved reference to that other definition. Therefore we'll get a (correct) link-time error like this:

Undefined symbols:
"_add", referenced from:
_main in cc-y1jXIr.o

By contrast, GNU C89 mode (used by default in older versions of GCC) is the C89 standard plus a lot of extensions. C89 doesn't have an inline keyword, but GCC recognizes it as an extension and just treats it as a hint to the optimizer.

There are several ways to fix this problem:

  1. Change add to a static inline function. This is usually the right solution if only one translation unit needs to use the function. static inline functions are always resolved within the translation unit, so you won't have to add a non-inline definition of the function elsewhere in your program.
  2. Remove the inline keyword from this definition of add. The inline keyword is not required for a function to be inlined, nor does it guarantee that it will be. Some compilers ignore it completely. Clang treats it as a mild suggestion from the programmer.
  3. Provide an external (non-inline) definition of add somewhere else in your program. The two definitions must be equivalent!
  4. Compile in the GNU C89 dialect by adding -std=gnu89 to the set of Clang options. This option is only recommended if the program source cannot be changed or if the program also relies on additional C89-specific behavior that cannot be changed.

All of this only applies to C code; the meaning of inline in C++ is very different from its meaning in either GNU89 or C99.

What is wrong with using inline functions?

It worth pointing out that the inline keyword is actually just a hint to the compiler. The compiler may ignore the inline and simply generate code for the function someplace.

The main drawback to inline functions is that it can increase the size of your executable (depending on the number of instantiations). This can be a problem on some platforms (eg. embedded systems), especially if the function itself is recursive.

I'd also recommend making inline'd functions very small - The speed benefits of inline functions tend to diminish as the function grows in size. At some point the overhead of the function call becomes small compared to the execution of the function body, and the benefit is lost.



Related Topics



Leave a reply



Submit