Why including cpp makes different result - c++11

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?

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.

Related

Why does this std::map not display in a useable way in the watch window of Visual C++?

I'm unable to view certain std::map in the watch window. Looking into the .natvis file, there are multiple implementations for std::map. Is there a way to select one or the other?
https://developercommunity.visualstudio.com/content/problem/1056550/im-unable-to-inspect-a-variable-of-type-stdmap-in.html
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <set>
#include <memory>
typedef std::shared_ptr<std::string> PTR_STRING;
typedef std::map<PTR_STRING, std::size_t> accessFunction2Order;
typedef std::set<accessFunction2Order> setOfAccessFunction2Order;
typedef std::map<std::vector<std::size_t>, setOfAccessFunction2Order> A2B;
typedef std::map<PTR_STRING, std::shared_ptr<A2B> > MAP;
int main()
{ MAP s{
{ std::make_shared<std::string>("asdasdasdasdasdasdasdasdasdasd"),
std::make_shared<A2B>()
}
};
const auto &r1 = *s.begin();
}
The map s cannot be watched (something regarding std::_Tree<> being displayed). Curiously a reference to the first element can.
The problem is caused by a (I think hardcoded) limit in the visual studio debugger.
In order to display one variable, the debugger is adapting what he finds in the .natvis file -- but he gives up after some fixed number of attempts to resolve a type.
The solution to this problem is to use something like std::any
(or boost::any for those of us not blessed with being able to use an uptodate C++ version)
to break this STL type into chunks the debugger can deal with.
This is of course only a workaround.
Let's hope that this problem will be solved soon.
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <set>
#include <any>
#include <memory>
typedef std::shared_ptr<std::string> PTR_STRING;
typedef std::map<PTR_STRING, long> accessFunction2Order;
typedef std::set<accessFunction2Order> setOfAccessFunction2Order;
#if 1
typedef std::map<std::vector<std::size_t>, std::any> A2B;
#else
typedef std::map<std::vector<std::size_t>, setOfAccessFunction2Order> A2B;
#endif
typedef std::map<PTR_STRING, std::shared_ptr<A2B> > MAP;
typedef std::shared_ptr<std::size_t> PTR_INT;
int main()
{ const MAP s{
{ std::make_shared<std::string>("asdasdasdasdasdasdasdasdasdasd"),
std::make_shared<A2B>()
}
};
}

Save list of files in array

I am making a C++ program which should be able to list the files from particular directory and save each file name as a string(which will be processed further for conversion). Do I need array of strings? Which functionality should I use. The number of files is not fixed.
Main thing is I can't enter the names manually. I must accept the names from the list generated.
In this case you want to use a vector:
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<string> file_names;
file_names.push_back("file1.txt");
file_names.push_back("file2.txt");
file_names.push_back("file3.txt");
file_names.push_back("file4.txt");
return 0;
}
Have you thought about using some command line tools to deal with this? Even input redirection will work for this. Example:
./Cpp < echo somedir/*
Where Cpp is the name of your compiled binary, and somedir is the directory you want to read from
Then in your c++ program, you simply use std::cin to read each filename from standard in.
#include <vector>
#include <string>
#include <iterator> // std::istream_iterator, std::back_inserter
#include <algorithm> //std::copy
#include <iostream> // std::cin
int main()
{
std::vector<string> file_names;
// read the filenames from stdin
std::copy(std::istream_iterator<std::string>(std::cin), std::istream_iterator<std::string>(), std::back_inserter(file_names));
// print the filenames
std::copy(file_names.begin(), file_names.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
return 0;
}

initializer_lists of streams (C++11)

I'm trying to pass variable number of ofstreams over to a function that accepts an initializer_list but doesn't seem to work and throws all possible errors from the initializer_list structure and about how my function is with an array of ofstreams cannot be matched to any defined function.
Is it actually possible to pass a reference of ofstreams over in an initializer_list?
test.cpp
#include "extension.h"
ofstream outputFile, outputFile2;
int main(void) {
outputFile.open(("data_1.txt");
outputFile2.open("data_2.txt");
writeSomething({outputFile, outputFile2});
outputFile.close();
outputFile2.close();
}
extension.h
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <string.h>
#include <initializer_list>
using namespace std;
void writeSomething(initializer_list<ofstream&> args);
extension.cpp
#include "extension.h"
void writeSomething(initializer_list<ofstream&> args) {
for (auto f : args ) {
f << "hello" << endl;
}
}
clang 3.4 (trunk 194324) produces a pretty clear error message:
initializer_list:54:23: error: 'iterator' declared as a pointer to a
reference of type
'std::basic_ofstream<char> &'
typedef const _E* iterator;
So no, it is not possible. See also Error: forming pointer to reference type 'const std::pair&'… I can't understand this error.
(gcc 4.7.2 and 4.8.1 crashes on this code due to some internal compiler error. I have submitted a bugreport.)
What you could do instead is to pass a pointer instead of a reference, something like this:
#include <fstream>
#include <initializer_list>
using namespace std;
void writeSomething(initializer_list<ofstream*> args) {
for (auto f : args )
*f << "hello" << endl;
}
int main() {
ofstream outputFile("data_1.txt");
ofstream outputFile2("data_2.txt");
writeSomething({&outputFile, &outputFile2});
}
However, I would much rather use a std::vector instead. Using an initializer list for this purpose is very strange and confusing for me.

How to setup C/C++ project safely (file organisation)

I have a (large) C/C++ project that consists of both C and C++ languages. At some point it turned out that there are two C functions with identical names. Those functions are defined in two different *.c files in different locations. In general at the highest level, the project is C++. This problem was questioned and answered here
However still a question "how to organize those files safely" remains. How can I group such project so that there are no name conflicts, and I can be sure that proper function is called. Will writing a wrapper for each of those functions help?
That how it looks at the moment:
A.h //first declaration of function F
A.c //first definition of function F
B.h //second declaration of function F
B.c //second definition of function F
trying to make such thing:
extern "C"{
#include "A.h"
#include "B.h"
}
causes of course name conflict. What can I do to avoid this conflct, and have the robust code? Would such solution help:
A_Wrapper.h: //c++
extern "C"{
#include "A.h"
}
void WrapF_A(int x)
{
F(x);
}
B_Wrapper.h: //C++
extern "C"{
#include "B.h"
}
void WrapF_B(int x)
{
F(x);
}
and then in the program:
#include A_Wrapper.h
#include B_Wrapper.h
Modyfing each file in that project would be rather impossible as it cosists of hundreds of files, and i would probably damage some code rather. Is there a way to make an include file seen only in some part of the program?
EDIT:
So I created a simple project illustrating the problem, and tried to apply the hints given by doctorlove. However still multiple definition of F error occurs. What should I change? Project files:
A.h:
#ifndef A_H_INCLUDED
#define A_H_INCLUDED
int F(int x);
#endif // A_H_INCLUDED
A.c
#include "A.h"
int F(int x)
{
return x*x;
}
AWrapper.h:
#ifndef AWRAPPER_H_INCLUDED
#define AWRAPPER_H_INCLUDED
int AF(int x);
#endif // AWRAPPER_H_INCLUDED
AW.cpp:
#include "AWrapper.h"
extern "C"{
#include "A.h"
}
int AF(int x)
{
return F(x);
}
B.h:
#ifndef B_H_INCLUDED
#define B_H_INCLUDED
int F(int x);
#endif // B_H_INCLUDED
B.c:
#include "B.h"
int F(int x)
{
return -x*x;
}
BWrapper.h:
#ifndef BWRAPPER_H_INCLUDED
#define BWRAPPER_H_INCLUDED
int BF(int x);
#endif // BWRAPPER_H_INCLUDED
BW.cpp:
#include "BWrapper.h"
extern "C"{
#include "B.h"
}
int BF(int x)
{
return F(x);
}
Go with your wrapper idea, but write a facade (see also here) that exposes what you need from A, and what you need from B not all the functions in there.
You will end up with something like
//header Wrap_A.h
#ifndef WRAP_A_INCLUDED
#define WRAP_A_INCLUDED
//for some input Data left as an exercise for the reader...
double solve_with_A(Data data);
#endif
//header Wrap_B.h
#ifndef WRAP_B_INCLUDED
#define WRAP_B_INCLUDED
//for some input Data...
double solve_with_B(Data data);
#endif
Then make two cpp files that include all the conflicting headers files, those from A in A.cpp and those from B in B.cpp, so the conflicts don't happen. The solve_with_A and solve_with_B functions will then call all the things they need without without leaking them to the whole program and causing conflicts.
You might have to give some thought to what Data will actually be. You could define your own types, one for A and one for B. Just avoid exposing the implementation details in your wrapping/facade headers.
If headers are causing you pain, firewall them off in the naughty corner.
EDIT
Given you have two functions, F, if you put all the sources into one project the linker should and will complain it can see both. Instead, you need to make two static libraries, and just expose the wrapped version to your main project.

Why is this simplest C++0x code not valid?

I encountered a weird problem just now.
The source code is simple and self-evident as follows:
#include <vector>
#include <iostream>
#include <functional>
using namespace std;
using namespace std::tr1;
template<class T_>
void show_size(T_ coll)
{
cout << coll.size();
}
int main()
{
vector<int> coll;
coll.push_back(1);
show_size(ref(coll));
return 0;
}
The VC++ 2010 reports:
error C2039: 'size' : is not a member of 'std::tr1::reference_wrapper<_Ty>'
As we know, reference_wrapper can automatically convert itself to its underlying type, here is vector<int>. Why is such simple code not valid?
No it can't that's the whole point of the reference wrapper, because it doesn't decay from the reference, unless explicitly requested using .get()
Edit: don't mix up the boosts reference wrapper with the standard one, the boost one actually has implicit conversion (but the target functionality is a little bit different)

Resources