What part of regex is supported by GCC 4.9? - regex

I don't get this. GCC is supposed to support but accoriding to their
http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.tr1
Status page "7 Regular Expressions are not supported".
But then at "28 Regular expressions" - they are checked as supported
http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.2011
Could you please explain what is actually the standard and what is not?

GCC 4.9 does indeed support the C++11 <regex> functionality but not the tr1 version. Note that the difference is that parts (all?) of the latter exist within a tr1:: namespace while the C++11 <regex> is within namespace std. There's not much point to going backwards and adding in tr1 support when C++11 has been published for some time now.

Following information can be found from GCC 4.9 release notes:
"Support for various C++14 additions have been added to the C++ Front End, on the standard C++ library side the most important addition is support for the C++11 regex"
If you want to install the latest GCC4.9 version to try by yourself you can follow below SO link:
How do I compile and run GCC 4.9.x?
Here is the sample program which has compiled using gcc4.9 and subsequent run.
//Sample Program
#include <regex>
#include <iostream>
using namespace std;
int main() {
regex reg("[0-9]+");
if (regex_match("123000", reg)) {
cout << "It's a match!" <<endl;
}
return 0;
}
$g++ -std=c++11 foo.cpp -o foo
$ g++ -v
Using built-in specs.
COLLECT_GCC=/home/mantosh/gcc-4.9.0/bin/g++
COLLECT_LTO_WRAPPER=/home/mantosh/gcc-4.9.0/libexec/gcc/x86_64-unknown-linux-gnu/4.9.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: /home/mantosh/objdir/../gcc-4.9.0/configure --disable-multilib --prefix=/home/mantosh/gcc-4.9.0
Thread model: posix
gcc version 4.9.0 (GCC)
$ ./foo
It's a match!

Related

Do I still have to link -std=c++11? [duplicate]

I have a piece of code that looks like the following. Let's say it's in a file named example.cpp
#include <fstream>
#include <string> // line added after edit for clarity
int main() {
std::string filename = "input.txt";
std::ifstream in(filename);
return 0;
}
On a windows, if I type in the cmd the command g++ example.cpp, it will fail. It's a long list of errors I think mostly due to the linker complaining about not being able to convert from string to const char*.
But if I run the compiler using an additional argument like so: g++ -std=c++17 example.cpp, it will compile and work fine with no problems.
What happens when I run the former command? I'm guessing a default version standard of the C++ compiler gets called, but I don't know which? And as a programmer/developer, should I always use the latter command with the extra argument?
If your version of g++ is later than 4.7 I think you can find the default version of C++ standard supported like so:
g++ -dM -E -x c++ /dev/null | grep -F __cplusplus
An example from my machine:
mburr#mint17 ~ $ g++ --version | head -1
g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
mburr#mint17 ~ $ g++ -dM -E -x c++ /dev/null | grep -F __cplusplus
#define __cplusplus 199711L
Some references:
Details on the g++ options used
Why this only works for g++ 4.7 or later
g++ man page actually tells what is the default standard for C++ code.
Use following script to show the relevant part:
man g++ | col -b | grep -B 2 -e '-std=.* This is the default'
For example, in RHEL 6 g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-23), the output:
gnu++98
GNU dialect of -std=c++98. This is the default for C++ code.
And in Fedora 28 g++ (GCC) 8.1.1 20180502 (Red Hat 8.1.1-1), the output:
gnu++14
gnu++1y
GNU dialect of -std=c++14. This is the default for C++ code. The name gnu++1y is deprecated.
You can also check with gdb
$ g++ example.cpp -g Compile program with -g flag to generate debug info
$ gdb a.out Debug program with gdb
(gdb) b main Put a breakpoint at main
(gdb) run Run program (will pause at breakpoint)
(gdb) info source
Prints out something like:
Current source file is example.cpp
Compilation directory is /home/xxx/cpp
Located in /home/xxx/cpp/example.cpp
Contains 7 lines.
Source language is c++.
Producer is GNU C++14 6.3.0 20170516 -mtune=generic -march=x86-64 -g.
Compiled with DWARF 2 debugging format.
Does not include preprocessor macro info.
There is the standard used by compiler: Producer is GNU C++14
If you recompile your program using -std=c++11 (for example), gdb detects it:
Producer is GNU C++11
I believe that it is possible to tell by looking at the man page (at least for g++):
Under the description of -std, the man page lists all C++ standards, including the GNU dialects. Under one specific standard, it is rather inconspicuously stated, This is the default for C++ code. (there is an analogous statement for C standards: This is the default for C code.).
For instance, for g++/gcc version 5.4.0, this is listed under gnu++98/gnu++03, whereas for g++/gcc version 6.4.0, this is listed under gnu++14.
I'm guessing a default version of the C++ compiler gets called, but I don't know which?
This is only guessable by reading the documentation of your particular compiler version.
If using a recent GCC, I recommend first to understand what version are you using by running
g++ -v
or
g++ --version
and then refer to the version of the particular release of GCC. For example for GCC 7, read GCC 7 changes etc
Alternatively, run
g++ -dumpspecs
and decipher the default so called spec file.
BTW, you could ensure (e.g. in some of your common header file) that C++ is at least C++17 by coding
#if __cplusplus < 201412L
#error expecting C++17 standard
#endif
and I actually recommend doing it that way.
PS. Actually, think of C++98 & C++17 being two different languages (e.g. like Ocaml4 and C++11 are). Require your user to have a compiler supporting some defined language standard (e.g. C++11), not some particular version of GCC. Read also about package managers.
If you are using the GCC compiler, you can find it on the man pages:
man g++ | grep "This is the default for C++ code"
Typing g++ --version in your command shell will reveal the version of the compiler, and from that you can infer the default standard. So you can't tell directly but you can infer it, with some effort.
Compilers are supposed to #define __cplusplus which can be used to extract the standard that they purport to implement at compile time; but many don't do this yet.
(And don't forget to include all the C++ standard library headers you need: where is the one for std::string for example? Don't rely on your C++ standard library implementation including other headers automatically - in doing that you are not writing portable C++.)
Your question is specific to gnu compilers, so probably better to tag it appropriately, rather than just C++ and C++11.
Your code will compile with any compilers (and associated libraries) compliant with C++11 and later.
The reason is that C++11 introduced a std::ifstream constructor that accepts a const std::string &. Before C++11, a std::string could not be passed, and it would be necessary in your code to pass filename.c_str() rather than filename.
According to information from gnu, https://gcc.gnu.org/projects/cxx-status.html#cxx11, gcc.4.8.1 was the first version to fully support C++11. At the command line g++ -v will prod g++ to telling you its version number.
If you dig into documentation, you might be able to find the version/subversion that first supported enough features so your code - as given - would compile. But such a version would support some C++11 features and not others.
Since windows isn't distributed with g++, you will have whatever version someone (you?) has chosen to install. There will be no default version of g++ associated with your version of windows.
The default language standards for both C and C++ are specified in the GCC Manuals. You can find these as follows:
Browse to https://gcc.gnu.org/onlinedocs/
Select the GCC #.## Manual link for the version of GCC you are interested in, e.g. for GCC 7.5.0:
https://gcc.gnu.org/onlinedocs/gcc-7.5.0/gcc/
Click the topic link Language Standards Supported by GCC, followed by the topic C++ Language (or C language). Either of these topics will have a sentence such as:
The default, if no C++ language dialect options are given, is -std=gnu++14.
The default, if no C language dialect options are given, is -std=gnu11.
The above two examples are for GCC 7.5.0.

Which C++ standard is the default when compiling with g++?

I have a piece of code that looks like the following. Let's say it's in a file named example.cpp
#include <fstream>
#include <string> // line added after edit for clarity
int main() {
std::string filename = "input.txt";
std::ifstream in(filename);
return 0;
}
On a windows, if I type in the cmd the command g++ example.cpp, it will fail. It's a long list of errors I think mostly due to the linker complaining about not being able to convert from string to const char*.
But if I run the compiler using an additional argument like so: g++ -std=c++17 example.cpp, it will compile and work fine with no problems.
What happens when I run the former command? I'm guessing a default version standard of the C++ compiler gets called, but I don't know which? And as a programmer/developer, should I always use the latter command with the extra argument?
If your version of g++ is later than 4.7 I think you can find the default version of C++ standard supported like so:
g++ -dM -E -x c++ /dev/null | grep -F __cplusplus
An example from my machine:
mburr#mint17 ~ $ g++ --version | head -1
g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
mburr#mint17 ~ $ g++ -dM -E -x c++ /dev/null | grep -F __cplusplus
#define __cplusplus 199711L
Some references:
Details on the g++ options used
Why this only works for g++ 4.7 or later
g++ man page actually tells what is the default standard for C++ code.
Use following script to show the relevant part:
man g++ | col -b | grep -B 2 -e '-std=.* This is the default'
For example, in RHEL 6 g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-23), the output:
gnu++98
GNU dialect of -std=c++98. This is the default for C++ code.
And in Fedora 28 g++ (GCC) 8.1.1 20180502 (Red Hat 8.1.1-1), the output:
gnu++14
gnu++1y
GNU dialect of -std=c++14. This is the default for C++ code. The name gnu++1y is deprecated.
You can also check with gdb
$ g++ example.cpp -g Compile program with -g flag to generate debug info
$ gdb a.out Debug program with gdb
(gdb) b main Put a breakpoint at main
(gdb) run Run program (will pause at breakpoint)
(gdb) info source
Prints out something like:
Current source file is example.cpp
Compilation directory is /home/xxx/cpp
Located in /home/xxx/cpp/example.cpp
Contains 7 lines.
Source language is c++.
Producer is GNU C++14 6.3.0 20170516 -mtune=generic -march=x86-64 -g.
Compiled with DWARF 2 debugging format.
Does not include preprocessor macro info.
There is the standard used by compiler: Producer is GNU C++14
If you recompile your program using -std=c++11 (for example), gdb detects it:
Producer is GNU C++11
I believe that it is possible to tell by looking at the man page (at least for g++):
Under the description of -std, the man page lists all C++ standards, including the GNU dialects. Under one specific standard, it is rather inconspicuously stated, This is the default for C++ code. (there is an analogous statement for C standards: This is the default for C code.).
For instance, for g++/gcc version 5.4.0, this is listed under gnu++98/gnu++03, whereas for g++/gcc version 6.4.0, this is listed under gnu++14.
I'm guessing a default version of the C++ compiler gets called, but I don't know which?
This is only guessable by reading the documentation of your particular compiler version.
If using a recent GCC, I recommend first to understand what version are you using by running
g++ -v
or
g++ --version
and then refer to the version of the particular release of GCC. For example for GCC 7, read GCC 7 changes etc
Alternatively, run
g++ -dumpspecs
and decipher the default so called spec file.
BTW, you could ensure (e.g. in some of your common header file) that C++ is at least C++17 by coding
#if __cplusplus < 201412L
#error expecting C++17 standard
#endif
and I actually recommend doing it that way.
PS. Actually, think of C++98 & C++17 being two different languages (e.g. like Ocaml4 and C++11 are). Require your user to have a compiler supporting some defined language standard (e.g. C++11), not some particular version of GCC. Read also about package managers.
If you are using the GCC compiler, you can find it on the man pages:
man g++ | grep "This is the default for C++ code"
Typing g++ --version in your command shell will reveal the version of the compiler, and from that you can infer the default standard. So you can't tell directly but you can infer it, with some effort.
Compilers are supposed to #define __cplusplus which can be used to extract the standard that they purport to implement at compile time; but many don't do this yet.
(And don't forget to include all the C++ standard library headers you need: where is the one for std::string for example? Don't rely on your C++ standard library implementation including other headers automatically - in doing that you are not writing portable C++.)
Your question is specific to gnu compilers, so probably better to tag it appropriately, rather than just C++ and C++11.
Your code will compile with any compilers (and associated libraries) compliant with C++11 and later.
The reason is that C++11 introduced a std::ifstream constructor that accepts a const std::string &. Before C++11, a std::string could not be passed, and it would be necessary in your code to pass filename.c_str() rather than filename.
According to information from gnu, https://gcc.gnu.org/projects/cxx-status.html#cxx11, gcc.4.8.1 was the first version to fully support C++11. At the command line g++ -v will prod g++ to telling you its version number.
If you dig into documentation, you might be able to find the version/subversion that first supported enough features so your code - as given - would compile. But such a version would support some C++11 features and not others.
Since windows isn't distributed with g++, you will have whatever version someone (you?) has chosen to install. There will be no default version of g++ associated with your version of windows.
The default language standards for both C and C++ are specified in the GCC Manuals. You can find these as follows:
Browse to https://gcc.gnu.org/onlinedocs/
Select the GCC #.## Manual link for the version of GCC you are interested in, e.g. for GCC 7.5.0:
https://gcc.gnu.org/onlinedocs/gcc-7.5.0/gcc/
Click the topic link Language Standards Supported by GCC, followed by the topic C++ Language (or C language). Either of these topics will have a sentence such as:
The default, if no C++ language dialect options are given, is -std=gnu++14.
The default, if no C language dialect options are given, is -std=gnu11.
The above two examples are for GCC 7.5.0.

How to compile C++ on Mac OS using TR1

I have a preexisting product that builds on Linux, and I'm trying to port it to Mac OS.
msoulier#merlin:~$ xcode-select -v
xcode-select version 2343.
msoulier#merlin:~$ g++ -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.3.0 (clang-703.0.29)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
The problem is that it uses the tr1/tuple library, and for some reason,
that is not in the default include path.
msoulier#merlin:~$ ls /usr/include/c++/4.2.1/tr1/tuple
/usr/include/c++/4.2.1/tr1/tuple
So it's there, which should be in the include path based on the
--with-gxx-include-dir option above,
And yet
msoulier#merlin:~$ cat hello.cpp
#include <iostream>
#include <tr1/tuple>
using namespace std;
int main(void) {
cout << "Hello, World!" << endl;
return 0;
}
msoulier#merlin:~$ g++ -o hello hello.cpp
hello.cpp:2:10: fatal error: 'tr1/tuple' file not found
#include <tr1/tuple>
^
1 error generated.
Why doesn't this just work?
Thanks.
Short answer: call clang++ with -stdlib=libstdc++, and the tr1 headers will be there.
Long answer:
The reason for your error and the 2 sets of C++ includes is that macOS/Xcode has two different C++ standard libraries you can build against: an old GNU libstdc++, and the new and modern LLVM libc++.
As of macOS 10.12 Sierra, the default is now libc++ and libstdc++ is deprecated. libstdc++ is quite old, v4.2.1, and predates C++11 (hence the tr1 headers). If you're going to be maintaining this code long-term, it'd be worth the time to make it C++11 compliant (i.e. #include <tuple>)
Update: Xcode 10 no longer allows building against libstdc++. Either update your codebase to use standard C++11 headers, or use Xcode 9 if that's really not an option.

Compiler option not working for unordered set C++11 feature

I am on Ubuntu 12.04 x64, using Eclipse Indigo w/ CDT plugin, and my g++ version is 4.7.3. I have added the compiler option -std=c++11 and the same option to discovery options (even though the code did not autocomplete when I wrote it).
Eclipse underlines parts of the following in red and gives warnings. However, the program, when run (ignoring errors), prints the expected result (Compiled with gcc 4.7\n 1 0\n). How can I fix this behavior?
#include <unordered_set>
#include <iostream>
using namespace std;
int main()
{
unordered_set<int> s; // Symbol unordered_set cannot be resolved
cout << "Compiled with gcc " << __GNUC__ << '.' << __GNUC_MINOR__ << endl;
s.insert(0); // Method insert cannot be resolved
s.insert(1); // Method insert cannot be resolved
s.insert(0); // Method insert cannot be resolved
for(auto i = s.begin(); i != s.end(); ++i) cout << ' ' << (*i);
// Method begin and end cannot be resolved
cout << endl;
return 0;
}
This is what Eclipse calls in command line:
...$ gcc -E -P -v -dD -std=c++11 .../specs.c
Using built-in specs.
...
gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-2ubuntu1~12.04)
After turning off the -std=c++11 compiler option for my C compiler (as it shouldn't be needed there anyway) - but keeping it on for the C++ compiler, the output printed to the console is as follows.
...$ g++ -E -P -v -dD -std=c++11 .../specs.cpp
Using built-in specs.
...
gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-2ubuntu1~12.04)
And, regardless of the errors Eclipse shows me, the output is still the same, showing the unordered set works and was compiled properly. This is clearly just an issue before the build. If my indexer isn't parsing properly before the build, how is the set working at runtime?
The compiler you are using may not include support for C++11, check your man page or IDE documentation and it will tell you if there is support or not.
Your problem is that the file's extension is .c instead of .cpp (or .cc), which causes it to be compiled with gcc instead of g++.
This means it is treated as pure C code instead of C++11, which makes it unsurprising that it won't compile.
I gave up because there was simply nothing else I could do, purged my my system of eclipse and my ~/.eclipse folder, downloaded Kepler and its CDT version, and now everything works.

C++ TR1 Regular Expressions Not Available

I'm trying to utilize the 'TR1' regular expression extensions for some C++ string parsing.
I've read that the <regex> header and namespace std::tr1 are required for this
I can compile with the <regex> header present(though it forces me to use either the flag, -std=c++0x or -std=gnu++0x)
However, when I attempt to use the std::tr1 namespace in my program, compiling fails with message that tr1 "is not a namespace name". I cant do things like,
std::tr1::regex rx("mypattern");
I've read that TR1 regular expressions have been supported since gcc 4.3.0. I'm using g++ through gcc 4.4.5.
Am I missing something?
g++ 4.7 doesn't implement regular expressions yet.
But despite that fact, in C++11 regex has been moved from the namespace std::tr1 to std. So, instead of std::tr1::regex, you should write std::regex:
std::regex rx("mypattern");
I don't know for which g++ versions before 4.7 this applies, too. But this ideone example compiles fine with g++ 4.7. However, remember that the regex implementation isn't implemented in this compiler version.