I have some problems with building my c++ app with make.
I have such c++ code:
#include <string>
#include <iostream>
#include <filesystem>
using namespace std;
namespace fs = std::filesystem;
int main()
{
auto iter = fs::directory_iterator(fs::current_path());
while(iter._At_end())
{
cout << iter->path() << endl;
}
return 0;
}
I am trying to compile object file with command:
g++-9 -std=c++17 -Wall -Wextra -pthread -lstdc++fs -c -o main.o main.cpp
But I have this error:
main.cpp:12:16: error: ‘class std::filesystem::__cxx11::directory_iterator’ has no member named ‘_At_end’
12 | while(iter._At_end())
| ^~~~~~~
So, I cant use members of classes of std::filesystem namespace but if I wanna use only class(for example std::filesystem::path), so everything is ok.
Versions of soft:
g++-9 (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
GNU Make 4.2.1
Hope you'll help me.
Just don't use _At_end() and everything will be ok.
Related
I have two source files: main.cxx and env.cxx. And main.cxx depends on env.cxx
If I compile them with
c++ -fmodules-ts -std=c++20 -Wall -g env.cxx main.cxx, then everything works well.
But if I compile them with
c++ -fmodules-ts -std=c++20 -Wall -g -c env.cxx
c++ -fmodules-ts -std=c++20 -Wall -g -c main.cxx
c++ -fmodules-ts -std=c++20 -Wall -g env.o main.o
I get segmentation fault.
I do not know whether it is a gcc bug or not, because it works well again if I rewrite them in c++17 style, removing the module declarations.
My compiler is gcc 11.1.0 (The newest version up to now)
Here is env.cxx:
module;
#include <cstdlib>
#include <string>
#include <string_view>
#include <stdexcept>
export module env;
export namespace env
{
std::string get_env(const char* name)
{
char* p = ::getenv(name);
if (p == nullptr)
throw std::runtime_error("environment variable not found");
return std::string(p);
}
// These two functions are useless this time.
std::string get_env(const std::string& name)
{
return get_env(name.data());
}
std::string get_env(std::string_view name)
{
std::string s{name};
return get_env(s.data());
}
}
And main.cxx
module;
#include <iostream>
#include <fstream>
import env;
export module main;
int main(int argc, char** argv)
{
std::cout << env::get_env("HOME") << std::endl;
return 0;
}
Can you reproduce this?
Update 2021.06-19 15:44
In fact the two compiling commands above both work well, and the way that produces segfault is actually:
c++ -fmodules-ts -std=c++20 -Wall -g -c env.cxx
c++ -fmodules-ts -std=c++20 -Wall -g -c main.cxx
c++ -fmodules-ts -std=c++20 -Wall -g main.o env.o
Note that the place of main.o and env.o has been changed.
I am trying to compile this code with MinGW g++ (i686-win32-dwarf-rev0, Built by MinGW-W64 project) 8.1.0
#include <bits/stdc++.h>
using namespace std;
int main()
{
map<int, int> mmap;
mmap[0]=10;
mmap[1]=20;
mmap[2]=30;
mmap[3]=40;
mmap[4]=50;
for(auto [x,y]:mmap){
cout<<x<<"->"<<y<<endl;
}
return 0;
}
Compiling with c++11 flag gives this
E:\Code>g++ temp.cpp -std=c++11
temp.cpp: In function 'int main()':
temp.cpp:89:14: warning: structured bindings only available with -std=c++17 or -std=gnu++17
for(auto [x,y]:mmap){
and compiling with c++17 flag gives lines and lines of errors.
g++ temp.cpp -std=c++17
OK, so I figured this out and this came out to be the very first line
#include <bits/stdc++.h>
Including iostream and map instead of the above line results in a clean compilation.
#include<iostream>
#include<map>
Now I have one more reason as to Why should I not #include <bits/stdc++.h>?
I know there are many similar topics but there are equally many unique mistakes that may lead to this problem (so I think). Therefore I ask, after some research.
My problem is that the compiler, GNU GCC, when compiling one file does not see my namespace declared in another file. The IDE (CodeBlocks) evidently does see it as it auto-completes the name of the namespace. I tried to isolate the problem and came up with this:
File main.cpp:
namespace MyName
{
int MyVar;
}
#include "T1.cpp"
int main()
{
return 0;
}
File T1.cpp:
using namespace MyName;
error: 'MyName' is not a name-space name.
In my project I have a header file, say T1.h, and an implementation file T1.cpp — and MyName isn't accessible in either of them.
Any help or guidance would be appreciated.
What's happening is that CodeBlocks is compiling both main.cpp and T1.cpp. Here is what happens when you try to compile each one:
main.cpp:
$ g++ main.cpp
$
T1.cpp
$ g++ T1.cpp
T1.cpp:1:17: error: ‘MyName’ is not a namespace-name
using namespace MyName;
^
T1.cpp:1:23: error: expected namespace-name before ‘;’ token
using namespace MyName;
^
$
T1.cpp, when compiled on it's own, has no knowledge of MyName. To fix this, don't include .cpp files, and put your declarations in header files.
Edit: From what I gather, this may be a better way to organize your example:
T1.h:
namespace MyName {
extern int MyVar;
}
T1.cpp
#include "T1.h"
int MyName::MyVar = 5;
main.cpp
#include "T1.h"
#include <iostream>
using namespace MyName;
int main()
{
std::cout << MyVar << std::endl;
return 0;
}
Now it will compile correctly:
$ g++ -c T1.cpp -o T1.o
$ g++ -c main.cpp -o main.o
$ g++ T1.o main.o
$ ./a.out
5
Okay, so I have
tmp.cpp:
#include <string>
int main()
{
std::to_string(0);
return 0;
}
But when I try to compile I get:
$ g++ tmp.cpp -o tmp
tmp.cpp: In function ‘int main()’:
tmp.cpp:5:5: error: ‘to_string’ is not a member of ‘std’
std::to_string(0);
^
I'm running g++ version 4.8.1. Unlike all the other references to this error that I found out there, I am not using MinGW, I'm on Linux (3.11.2).
Any ideas why this is happening? Is this standard behaviour and I did something wrong or is there a bug somewhere?
you may want to specify the C++ version with
g++ -std=c++11 tmp.cpp -o tmp
I don't have gcc 4.8.1 at hand , but in older versions of GCC,
you can use
g++ -std=c++0x tmp.cpp -o tmp
At least gcc 4.9.2 I believe also support part of C++14 by specifying
g++ -std=c++1y tmp.cpp -o tmp
Update:
gcc 5.3.0 (I am using the cygwin version) supports both -std=c++14 and -std=c++17 now.
to_string works with the latest C++ versions like version 11. For older versions you can try using this function
#include <string>
#include <sstream>
template <typename T>
std::string ToString(T val)
{
std::stringstream stream;
stream << val;
return stream.str();
}
By adding a template you can use any data type too.
You have to include #include<sstream> here.
Okay, so I have
tmp.cpp:
#include <string>
int main()
{
std::to_string(0);
return 0;
}
But when I try to compile I get:
$ g++ tmp.cpp -o tmp
tmp.cpp: In function ‘int main()’:
tmp.cpp:5:5: error: ‘to_string’ is not a member of ‘std’
std::to_string(0);
^
I'm running g++ version 4.8.1. Unlike all the other references to this error that I found out there, I am not using MinGW, I'm on Linux (3.11.2).
Any ideas why this is happening? Is this standard behaviour and I did something wrong or is there a bug somewhere?
you may want to specify the C++ version with
g++ -std=c++11 tmp.cpp -o tmp
I don't have gcc 4.8.1 at hand , but in older versions of GCC,
you can use
g++ -std=c++0x tmp.cpp -o tmp
At least gcc 4.9.2 I believe also support part of C++14 by specifying
g++ -std=c++1y tmp.cpp -o tmp
Update:
gcc 5.3.0 (I am using the cygwin version) supports both -std=c++14 and -std=c++17 now.
to_string works with the latest C++ versions like version 11. For older versions you can try using this function
#include <string>
#include <sstream>
template <typename T>
std::string ToString(T val)
{
std::stringstream stream;
stream << val;
return stream.str();
}
By adding a template you can use any data type too.
You have to include #include<sstream> here.