Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
332 views
in Technique[技术] by (71.8m points)

c++ - How to tell compiler to NOT optimize certain code away?

Is there a way to tell the compiler (g++ in my case) to not optimize certain code away, even if that code is not reachable? I just want those symbols in the object file.

Example: Here is a simple function, and I do want this function to be compiled, even if it's never called.

void foo(){
  Foo<int> v;
}

If there is no official compiler directive, is there a trick to make the compiler think that it's an important function? Or at least make it think that it can't safely be ignored? I tried something like this:

extern bool bar;
void foo(){
  if(bar){
    Foo<int> v;
  }
}

but that didn't seem to do it.

(If you really want to know why I on earth would want that -- it has to do with this question, where, instead of explicit template instantiation with template class Foo<int> I simply want to be able to write Foo<int> v, since in many cases that's easier since it implicitly instantiates all functions needed, and it does work fine in debug mode without optimizations ...)

UPDATE:

Here is what I want to do (as a compilable mini example):

foo.h (such files are given to me and not changeable)

template<class T>
struct Foo {
  T val_;
  Foo(T val) : val_(val) {
      // heavy code, long compile times
  }
};

foo-instantiation.cpp

#include "foo.h"
void neverCalled() {
  Foo<int> f(1);
}

// The standard way to instantiate it is this:
// template class Foo<int>;
// but in reality it is often hard to find out 
// exactly what types I have to declare.
// Usage like Foo<int> f(1); will instantiate all
// dependent types if necessary.

foo-decl.h (an interface that I extracted from foo.h)

template<class T>
struct Foo {
  T val_;
  Foo(T val); // no heavy code, can include anywhere and compile fast
};

main.cpp

#include <iostream>
#include "foo-decl.h"

int main(int argc, char** argv){
  Foo<int> foo(1);
  return 0;
}

Compilation (no optimization)

g++ -c main.cpp
g++ -c foo-instantiation.cpp
g++ main.o foo-instantiation.oo

Compilation (optimization)

g++ -O2 -c main.cpp
g++ -O2 -c foo-instantiation.cpp
g++ main.o foo-instantiation.oo
main.o(.text+0x13): In function `main':
: undefined reference to `Foo<int>::Foo(int)'
collect2: ld returned 1 exit status
  • I tried precompiled headers instead, but the template instantiation method makes for much faster compilation.
  • Compiling foo-instantiation.cpp without optimization is not so ideal because then the library code (foo.h and others) will run slower.
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You are running into the One Definition Rule. In one file you have a definition:

template<class T>
struct Foo {
  T val_;
  Foo(T val) : val_(val) {
      // heavy code, long compile times
  }
};

and in another a different definition:

template<class T>
struct Foo {
  T val_;
  Foo(T val); // no heavy code, can include anywhere and compile fast
};

This is explicitly not allowed in C++ (only one identical definition allowed) and if you break the rule your code may well seem to work sometimes, but what you actually have is the dreaded "undefined behaviour" - anything may happen depending on the phase of the moon (but more likely the internal state of the compiler at certain critical junctures).

Basically, you can't write code like that - sorry.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...