Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

different behavior depending on the optimization options

I found an example where the output is different depending on the optimization settings (-O3 vs none), yet GCC 4.8.2 produces no warnings, even with the -std=c++11 -Wall -pedantic options.

In this particular case, I'm assuming that "forgetting" the commented line in header.h is a mistake, and with -O3, c<int>::get() gets inlined.

However, is there any way to protect yourself against these kinds of mistakes -- a compiler or linker option perhaps?

header.h:

#ifndef HEADER_H
#define HEADER_H

template<class T>
struct c
{
   int get() { return 0; }
};

// template<> int c<int>::get();

#endif

imp.cpp:

#include "header.h"

template<> 
int c<int>::get()
{
   return 1;
}

main.cpp:

#include <iostream>
#include "header.h"

int main()
{
    c<int> i;
    std::cout << i.get() << '\n'; // prints 0 with -O3, and 1 without
}

build:

c++ -std=c++11 -pedantic -Wall -O3 -c imp.cpp
c++ -std=c++11 -pedantic -Wall -O3 -c main.cpp
c++ -std=c++11 -pedantic -Wall -O3 imp.o main.o
like image 239
MWB Avatar asked Sep 27 '26 10:09

MWB


1 Answers

  1. What you get if you have the line in your header-file, is a declaration of an explicit specialization for that member-function.

    Thus, main.cpp is assured of a definition in some other compilation-unit, and things work.

  2. If you leave it out, you have a violation of the ODR:

    That specific instantiation of your class-template is different in the compilation-units. Resulting in "ill-formed, no diagnostic required", so anything goes.

    And there is (currently?) no compiler-option to force gcc to diagnose it.

like image 71
Deduplicator Avatar answered Sep 29 '26 23:09

Deduplicator