Почему включение cpp приводит к другому результату

#c 11 #boost

#c 11 #повышение

Вопрос:

я узнал, что ключевое слово «include» — это просто копировать и вставлять.

Но включение файла cpp приводит к другому результату компиляции. (gcc6 ~ 8 boost1.69)

 // main.cpp
#include <iostream>

// I'll move next code to why.cpp
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/insert_linebreaks.hpp>
#include <boost/archive/iterators/remove_whitespace.hpp>

void testFunc()
{
    using namespace boost::archive::iterators;
    typedef transform_width<binary_from_base64<remove_whitespace<std::string::const_iterator>>, 8, 6> ItBinaryT;

    std::string input;
    std::string output(ItBinaryT(input.begin()), ItBinaryT(input.end()));
}
// -----------------------------

int main()
{
    return 0;
}
  

Приведенный выше код скомпилирован без предупреждения.

Но я заменяю некоторый код на включение cpp..

 // main.cpp
#include <iostream>
#include "why.cpp" // <----------
int main()
{
    return 0;
}
  
 // why.cpp - just copyamp;paste
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/insert_linebreaks.hpp>
#include <boost/archive/iterators/remove_whitespace.hpp>

void testFunc()
{
    using namespace boost::archive::iterators;
    typedef transform_width<binary_from_base64<remove_whitespace<std::string::const_iterator>>, 8, 6> ItBinaryT;

    std::string input;
    std::string output(ItBinaryT(input.begin()), ItBinaryT(input.end()));
}
  

Это вызывает предупреждение [-Wsubobject-linkage]

  • ~~ имеет поле ~ ~, тип которого использует анонимное пространство имен

  • ~~ имеет базу ~~, тип которой использует анонимное пространство имен

Пожалуйста, посмотрите на эту ссылку:https://wandbox.org/permlink/bw53IK2ZZP5UWMGk

В чем эта разница?

Комментарии:

1. включение файла .cpp — плохая идея!!!!

2. Я знаю, но мне действительно нужно это для UnityBuild..

3. Расширение включаемого файла здесь не имеет значения, просто эти заголовки включаются транзитивно. Довольно странно … может быть, причуда компилятора? Clang, похоже, молчит…

4. @AnaHumid что вы имеете в виду, что вам «нужно это для UnityBuid», Вам никогда не нужно включать cpp файлы

5. @bolov Я хотел бы сократить время сборки. поэтому я пытаюсь включить весь cpp-файл в один cpp-файл. en.wikipedia.org/wiki/Single_Compilation_Unit

Ответ №1:

Ваш компилятор обрабатывает основной файл CPP особым образом, исходя из предположения, что вещи, определенные в нем, вряд ли будут иметь более одного определения, и поэтому некоторые тесты на возможное нарушение правила одного определения не выполняются внутри этого файла. Использование #include выводит вас за пределы этого файла.

Я бы посоветовал просто не использовать -Wsubobject-linkage , поскольку его логика основана на эвристике, которая неприменима к вашему коду.