-std=c++ 98 and OS X 10.10 - c++

I'm currently trying to compiling my program with the -std=c++98 flag on OS X 10.10:
clang++ -std=c++98 -pedantic -W -Wall -Werror *.cpp
g++ -std=c++98 -pedantic -W -Wall -Werror *.cpp
Strangely when I compile with OS 10.10 no error are showed while some are showed with a GNU/Linux distribution.
With the GNU/Linux distribution I have some errors because I use s.open(file); instead of s.open(file.c_str()); but on OS X no error, even by using s.open(file);.
Maybe there is just a link between this error and the filesystem of each OS?

You're correct. This code shouldn't compile under C++98:
#include <fstream>
#include <string>
int main() {
std::string file("/tmp/foo.txt");
std::ifstream s;
s.open(file);
}
It's technically a bug in libc++, but it's one that I doubt that they will want to fix.
If you wanted, you could compile with libstdc++ as the standard library, which doesn't have this feature implemented (at least the version that apple distributes doesn't).
[10:13am][wlynch#watermelon /tmp] clang++ -std=c++98 -stdlib=libstdc++ foo.cc
foo.cc:7:12: error: no viable conversion from 'std::string' (aka 'basic_string<char>') to 'const char *'
s.open(file);
^~~~
/usr/include/c++/4.2.1/fstream:518:24: note: passing argument to parameter '__s' here
open(const char* __s, ios_base::openmode __mode = ios_base::in)
^
1 error generated.

The problem is that on OS X you're still using a C++11 implementation of the standard library, which includes such API changes as the ostream::open method accepting std::strings.
Changing the C++ standard with -std=c++98 does not affect the standard library being used, and libc++ does not implement C++98 (e.g., there's no #ifdef to remove those open(std::string) APIs when in C++98 mode) whereas I think libstdc++ does hide non-c++98 APIs when building in C++98 mode.

Related

In Visual Studio Code: "no template named 'initializer_list' in namespace 'std'"? [duplicate]

I wanted to compile C++11 source code within Mac Terminal but failed. I tried g++ -std=c++11, g++ -std=c++0x, g++ -std=gnu++11 and g++ -std=gnu++0x but nothing worked. Terminal always read unrecognized command line option. However, g++ -std=gnu and things like that worked fine (of course C++11 source code could not pass).
Which option should I use to turn on C++11 support?
By the way, the command line tool I'm using is installed within Xcode, and I'm pretty sure that they are up-to-date.
As others have pointed out you should use clang++ rather than g++. Also, you should use the libc++ library instead of the default libstdc++; The included version of libstdc++ is quite old and therefore does not include C++11 library features.
clang++ -std=c++11 -stdlib=libc++ -Weverything main.cpp
If you haven't installed the command line tools for Xcode you can run the compiler and other tools without doing that by using the xcrun tool.
xcrun clang++ -std=c++11 -stdlib=libc++ -Weverything main.cpp
Also if there's a particular warning you want to disable you can pass additional flags to the compiler to do so. At the end of the warning messages it shows you the most specific flag that would enable the warning. To disable that warning you prepend no- to the warning name.
For example you probably don't want the c++98 compatibility warnings. At the end of those warnings it shows the flag -Wc++98-compat and to disable them you pass -Wno-c++98-compat.
XCode uses clang and clang++ when compiling, not g++ (assuming you haven't customized things). Instead, try:
$ cat t.cpp
#include <iostream>
int main()
{
int* p = nullptr;
std::cout << p << std::endl;
}
$ clang++ -std=c++11 -stdlib=libc++ t.cpp
$ ./a.out
0x0
Thanks to bames53's answer for pointing out that I had left out -stdlib=libc++.
If you want to use some GNU extensions (and also use C++11), you can use -std=gnu++11 instead of -std=c++11, which will turn on C++11 mode and also keep GNU extensions enabled.

Compiling c++14 Code with Mac Terminal Compiler

I'm trying to code the BST ADT, and the specification we were given requires use of 'auto' that is only included in C++14. I'm trying to compile, but I keep getting errors that 'auto' is only included in C++14, so I'm just wondering if there's a different way to compile the code so that it includes C++14? In every previous project I've done (over the last three semesters) I've been able to compile the file (say called main.cpp) just by using the code:
g++ -o main main.cpp
I've tried the following compile code
g++ -std=c++14 -o main main.cpp
but when I do that, I get like 100 errors that look like
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/string:1002:86: error: member reference base type 'std::__1::basic_string::__self_view' (aka 'int') is not a structure or union
append(const _Tp& __t) { __self_view __sv = __t; return append(__sv.data(), __sv.size()); }
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/string:1002:99: error: member reference base type 'std::__1::basic_string::__self_view' (aka 'int') is not a structure or union
append(const _Tp& __t) { __self_view __sv = __t; return append(__sv.data(), __sv.size()); }
What do these even mean?
I figured out the reasons behind the errors (turned out to be templating mistakes), but in the end compiling with g++ -std=c++14 -o main main.cpp is working. I still don't really understand any of the compilation stuff though, so if someone could explain a little bit/ provide a link I would appreciate
(this is not an answer, but too long for a comment)
Where did you get your g++ from? On most modern Mac OS installs, it is a symlink for clang++. What does g++ --version print?
Certainly you're using libc++, not libstdc++. The __1 in the type names is a giveaway, along with the path to <string>.
And the error message ('std::__1::basic_string::__self_view' (aka 'int') is weird, too. basic_string::__self_view is a string_view, not an int.
if you use Unix based operating systems such as Linux and OS X try this:
clang++ -g -std=c++1y main.cpp -o main

Compile error: 'stoi' is not a member of 'std'

My code:
#include <iostream>
#include <string>
int main()
{
std::string test = "45";
int myint = std::stoi(test);
std::cout << myint << '\n';
}
Gives me the compile error:
error: 'stoi' is not a member of 'std'
int myint = std::stoi(test);
^
However, according to here, this code should compile fine. I am using the line set(CMAKE_CXX_FLAGS "-std=c++11 -O3") in my CMakeLists.txt file.
Why is it not compiling?
Update: I am using gcc, and running gcc --version prints out:
gcc (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010
In libstdc++, the definitions of stoi, stol, etc., as well as the to_string functions, are guarded by the condition
#if ((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
&& !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
I have had this fail on one platform before (namely Termux on Android), resulting in to_string not being available even with g++ 6.1 and the C++14 standard. In that case, I just did
#define _GLIBCXX_USE_C99 1
before including anything, and voilà, suddenly the functions existed. (You should put this first, or even on the command line, rather than just before including <string>, because another header may include <string> first, and then its include guards will keep it from ever seeing your macro.)
I did not investigate why this macro wasn't set in the first place. Obviously this is a cause for concern if you want your code to actually work (in my case I didn't particularly, but FWIW there were no problems.)
You should check if _GLIBCXX_USE_C99 is not defined, or if _GLIBCXX_HAVE_BROKEN_VSWPRINTF is defined (which may be the case on MinGW?)
std::stoi is a C++11 function. You have to use the -std=c++11 to enable it in both g++ and clang++. This is the actual issue, not a linking error or a specific preprocessor define.
$ cat test.cxx
#include <iostream>
#include <string>
int main()
{
std::string test = "45";
int myint = std::stoi(test);
std::cout << myint << '\n';
}
$ g++ -otest test.cxx
test.cxx: In Funktion »int main()«:
test.cxx:7:17: Fehler: »stoi« ist kein Element von »std«
int myint = std::stoi(test);
^
$ g++ -otest test.cxx -std=c++11
$ ./test
45
$
edit: I just saw that you used c++11. Are you sure that's making it into your compile options? Check the generated makefile and watch the executed commands to be certain.
Your version seems up to date, so there shouldn't be an issue. I think it may be related to gcc. Try g++ instead.(Most likely automatically linking issue. If you just run gcc on a C++ file, it will not 'just work' like g++ does. That's because it won't automatically link to the C++ std library, etc.). My second advise is try std::atoi.
# I have fixed the issue. std::stoi uses libstdc++. It is about The GNU Standard C++ Library. In gcc you have to link adding -lstdc++. However, in g++, libstdc++ is linked automatically.
using gcc and using g++
Pay attention how it is compiled
using g++: g++ -std=c++11 -O3 -Wall -pedantic main.cpp && ./a.out
using gcc: gcc -std=c++11 -O3 -Wall -pedantic -lstdc++ main.cpp && ./a.out
I think you should set flag like set(CMAKE_EXE_LINKER_FLAGS "-libgcc -lstdc++") (Not tested)
#include <cstdlib>
int myInt = std::atoi(test.c_str());
If you are using Cmake to compile, add line:
"add_definitions(-std=c++11)"
after find_package command.
Use 'set(CMAKE_CXX_STANDARD 11)' for Cmake

How to compile Hinnant's short_alloc allocator

I'd like to try the new Hinnant's short_alloc allocator that, as far as I can understand, replaces the old stack_alloc allocator. However, I can't manage to compile the vector example. g++ says:
~# g++ -std=c++11 stack-allocator-test.cpp -o stack-allocator-test
In file included from stack-allocator-test.cpp:6:0:
short_alloc.h:11:13: error: ‘alignment’ is not a type
short_alloc.h:11:22: error: ISO C++ forbids declaration of ‘alignas’ with no type [-fpermissive]
short_alloc.h:11:22: error: expected ‘;’ at end of member declaration
As far as I can tell, g++ complains about line 10 and 11:
static const std::size_t alignment = 16;
alignas(alignment) char buf_[N];
It seems that the compiler doesn't like the "expression version" of alignas but it expects just the "type-id version".
I'm using g++ 4.7.2 under Ubuntu 12.10.
~# g++ --version
g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
Probably I'm missing something obvious, but I can't figure it out. Any help would be appreciated. (Please don't tell me I have to upgrade to a newer g++, I'm too lazy to do that :)
g++-4.7.2 doesn't support alignas. From http://gcc.gnu.org/projects/cxx0x.html:
Alignment support | N2341 | GCC 4.8
Try using g++-4.8.0 or clang; alternatively you may be able to use the __attribute__((aligned)):
__attribute__((aligned (8))) char buf_[12];
Note that __attribute__((aligned)) only accepts certain integer constant expressions (literals, template parameters); it doesn't accept static const variables.

c++11: clang refuses numeric_limits<> in my template definition, while gcc accepts it - which is right?

The offending code:
template <class Bar,
size_t MAX_SIZE = std::numeric_limits<size_t>::max()>
size_t foo(Bar const& b) { omitted... }
It compiles fine on gcc 4.7.2 with -std=c++11. On clang 3.0 I get the following error:
foo.hpp:35:28: error: non-type template argument of type 'unsigned long' is not an integral constant expression
size_t MAX_SIZE = std::numeric_limits<size_t>::max()>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
As far as I can tell, I am supposed to be able to use numeric_limits in this way in c++11. Is clang wrong here, or am I unaware of something?
EDIT:
Compilation flags are: clang++ -o foo.o -c -W -Wall -Wextra -Werror -std=c++11 -stdlib=libc++ -g -I. foo.cpp
Your code compiles just fine with clang++ 3.2, see here.
I would say there is nothing wrong with your code but you should upgrade to a newer version of clang.
Note: The code doesn't compile with the Intel C++ Compiler 13.0.1 due to a compiler bug (thanks #Xeo):
Compilation finished with errors:
source.cpp(6): internal error: assertion failed: ensure_il_scope_exists: NULL IL scope (shared/cfe/edgcpfe/il.c, line 7439)
size_t MAX_SIZE = std::numeric_limits<size_t>::max()>
^
compilation aborted for source.cpp (code 4)
To use C++11 library features with clang you need to use the libc++ standard library implementation, otherwise you get the ancient library from GCC 4.1.2, which doesn't support C++11
See https://stackoverflow.com/a/14790442/981959 and https://stackoverflow.com/a/14150421/981959 and many other questions.