How to tell the compiler NOT to optimize certain code?

Is there a way to tell the compiler (g ++ in my case) so as not to optimize specific code, even if that code is not available? I just need these characters in the object file.

Example: here is a simple function, and I want this function to be compiled even if it has never been called.

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

If there is no official compiler directive, is there a trick for the compiler to think that this is an important function? Or at least make him think that he cannot be safely ignored? I tried something like this:

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

but it doesn't look like that.

( , - , template class Foo<int> Foo<int> v, , ...)

UPDATE:

( -):

foo.h ( )

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 (, 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;
}

( )

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

()

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
  • , .
  • foo-instantiation.cpp , (foo.h ) .
+3
7

. :

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

- :

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

++ ( ), , , , , - "undefined" - (, , ).

, - .

+7

, , extern , , . , static, , - .

:

while(false) {
  foo();
}

foo() .

OTOH, , .

- , .

+4

#pragma. escape-, . gcc , , g++ . , , , , .

+2

, , , , . , - :

void instantiation()
{
   Foo<int> f;
   f; // mark the variable as if it is used.
}

// or:
Foo<int>* instantiation()
{
   Foo<int> *p = new Foo<int>();
   return p; // The compiler cannot know if p will be used, it must compile
}

, :

// .h
template <typename T>
class Foo
{
public:
   Foo( T const & value );
   void set( T const & ); // whatever else
private:
   T value_;
};

// template implementation another file, not included from .h
// instantiation.cpp??
template <typename T>
Foo<T>::Foo<T>( T const & value ) : value_(value) {}

template <typename T>
void Foo<T>::set( T const & v )
{
   value_ = value;
}

// explicit instantiation
template class Foo<int>;
template class Foo<double>;

// test.cpp
#include "header.h"
int main()
{
    Foo<int> f(5);
    f.set( 7 );

    Foo<char> f2; // linker error Foo<char>() not defined
}

, , . , .

: , , .

++ , . ( void f() { }, ), . , . [1], (std::vector:: push_back() std::vector push_back)

"" , , , , , , . , , STL, , .

gcc 4.2 gcc linux , , . (gcc- linux , 4.2, , 4.3 4.4 alredy ), , "" / .

ODR, . , . , ( , ): , (virtual/const-ness...) , () .

[1] , :

template <typename T>
struct Test
{
   void f() { std::cout << "f()" << std::endl; }
   void g() { std::cout << "g()" << std::endl; }
};
int main()
{
   Test<int> t;
   t.f(); // compiler generates Test<int>::f, but not Test<int>::g
}
+2

. C # , Delphi Pascal - {$ O-}, {$ O +} . , , .

, , , . , , , . , , , - , - .

+1

. , , ?

, , , , ( ).

0

:

volatile Foo<int> v;

. Intel ++ Microsoft Visual Studio 2008.

0

Source: https://habr.com/ru/post/1705118/


All Articles