0

l learned "include" keyword are just copy & paste.

But including cpp file makes different compile result. (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;
}

Above code compiled without warning.

But, I replace some code with include cpp..

// main.cpp
#include <iostream>
#include "why.cpp" // <----------
int main()
{
    return 0;
}
// why.cpp - just copy&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()));
}

It makes warning [-Wsubobject-linkage]

  • ~~ has a field ~~ whose type uses the anonymous namespace

  • ~~ has a base ~~ whose type uses the anonymous namespace

Please look at this link : https://wandbox.org/permlink/bw53IK2ZZP5UWMGk

What makes this difference?

muhammad tayyab
  • 727
  • 7
  • 18
AnaHumid
  • 19
  • 7
  • including .cpp file is bad idea!!!! –  Mar 22 '19 at 22:47
  • I know, but I really need it to UnityBuild.. – AnaHumid Mar 22 '19 at 22:58
  • The extension of the included file doesn't matter here, just including those headers transitively. Pretty odd... maybe a compiler quirk? Clang seems to be silent... – Dan Mašek Mar 22 '19 at 23:01
  • @AnaHumid what do you mean you "need it to UnityBuid" You should never need to include `cpp` files – bolov Mar 22 '19 at 23:05
  • @bolov I would like to reduce build time. so I try to include all cpp file into single cpp file. https://en.wikipedia.org/wiki/Single_Compilation_Unit – AnaHumid Mar 22 '19 at 23:18
  • @AnaHumid ... ummm ... I don't know what to say. I am very very skeptical of this technique. – bolov Mar 22 '19 at 23:21
  • @bolov Unity Builds are a fairly common technique but do lead to certain issues that you wouldnt normally have (missing includes might work because a cpp before you got them, or static functions in cpp might actually clash with each other because they are now part of the same compilation unit) – Borgleader Mar 22 '19 at 23:25
  • Thank you for your attention. But UnityBuild is not important. I wonder include keyword's secret feature. – AnaHumid Mar 22 '19 at 23:35
  • There's nothing special about including files. Unity builds are always troublesome and require adjustments to the way you write code for them to work. They can result in faster build times, but so can actually analyzing how you build and adjusting that process to be more efficient. – Retired Ninja Mar 22 '19 at 23:45
  • during preprocessing of your code by compilers include guards matter (i.e. pragma once), in your cpp you haven't added it, so you will have big duplication issues along the development way. – fiorentinoing Mar 23 '19 at 20:58
  • It's boost's header's doing. Those headers shouldn't be included as part of another header. Related: https://stackoverflow.com/questions/37722850/how-to-silence-whose-type-uses-the-anonymous-namespace-werror-gcc-version-4 – Swift - Friday Pie Mar 23 '19 at 22:58

1 Answers1

0

Your compiler treats the main CPP file specially under the assumption that things defined in it are very unlikely to have more than one definition and so some tests for possible violation of the One Definition Rule are not done inside that file. Using #include takes you outside that file.

I would suggest just not using -Wsubobject-linkage since its logic is based on a heuristic that is not applicable to your code.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278