0

Let's consider the following code:

output_data.hpp

#pragma once

#include <functional>
#include <cstddef>

namespace example {
    
using Callback = std::function<void(int)>;
struct OutputData {

    void * data = nullptr;
    std::size_t size = 5;
    Callback callback = nullptr;
};

}  // namespace example

buffer.hpp

#pragma once
#include <vector>

namespace example {

template <typename T>
struct Buffer {
    Buffer(std::size_t size);

    std::vector<T> buffer_;
};

} // namespace example

buffer.cpp

#include "buffer.hpp"
#include "output_data.hpp"

namespace example {

template <typename T>
Buffer<T>::Buffer(std::size_t size) : buffer_(size) 
{
}

template struct Buffer<OutputData>;

} // namespace example

main.cpp

#include <iostream>
#include <memory>
#include <functional>
#include "buffer.hpp"

namespace example {

using Callback = std::function<void(int)>;

struct OutputData {
    Callback callback = nullptr;
};

}

int main() {
    std::shared_ptr<int> ptr = std::make_shared<int>(5);

    example::Buffer<example::OutputData> buf(3);

    example::Callback simple_callback = [=](int a) {
        std::cout << a << *ptr << "\n";
    };

    buf.buffer_[1].callback = simple_callback;
}

[Godbolt][https://godbolt.org/z/EEzE7oerb]

The compilation ends without errors, while the execution ends with Segmentation Fault. Segfault is caused by the fact that in main.cpp I used a different struct than the one in buffer.cpp during explicit instantiation. Why was the code compiled without errors? Is it possible to detect such programming mistakes during compilation? Is there any warning flag for detecting such cases ?

sweet_sugar
  • 1,390
  • 3
  • 13
  • 22
  • 2
    Breaking the - One Definition Rule - No Diagnostic Required, see https://en.cppreference.com/w/cpp/language/definition _"... One and only one definition of every non-inline function or variable that is odr-used (see below) is required to appear in the entire program (including any standard and user-defined libraries). The compiler is not required to diagnose this violation, but the behavior of the program that violates it is undefined....."_ – Richard Critten Aug 10 '22 at 18:43
  • 1
    Reopening this question - I do not believe this question is asking [What exactly is One Definition Rule in C++?](https://stackoverflow.com/questions/4192170/what-exactly-is-one-definition-rule-in-c). OP seems to already understand what it is. – Drew Dormann Aug 10 '22 at 18:53

1 Answers1

3

Why was the code compiled without errors?

Credit to Richard Critten's comment for the source.

"The compiler is not required to diagnose this violation, but the behavior of the program that violates it is undefined"

Is it possible to detect such programming mistakes during compilation?

Yes, see below.

Is there any warning flag for detecting such cases ?

Your ODR violation does not exist during compilation of any single source file. It only exists during (after) linking.

g++ will, unless disabled, warn of ODR violations during link time if Link Time Optimization is enabled with the flag -flto

[Godbolt]

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180