I'm trying to learn new features/gimmicks of c++17, but then I got to std::byte and for some unknown reason I can't seem to be able to compile even most basic "hello world" type program with the type.
entire program:
#include <cstddef>
int main(int argc, char* argv[])
{
std::byte byte;
return 0;
}
compilation command:
g++ ./main.cpp
But the output is always:
./main.cpp: In function ‘int main(int, char**)’:
./main.cpp:4:10: error: ‘byte’ is not a member of ‘std’
std::byte byte;
I work on Ubuntu 18.04 with gcc 7.4.0. I have checked "/usr/include/c++/7.4.0/" and header file cstddef is there and byte seems to be defined.
I have also tried to use clang:
clang++ ./main.cpp
But the result was same. At this point I can only think that cstddef is corrupted/bugged. Are there any solutions to this?
As πάντα ῥεῖ pointed out in comment I was missing c++17 compile flag. Right compilation command:
g++ -std=c++17 ./main.cpp
If you use clang 5.0 (even with -std=c++17 flag) the same error occur.
In that case, to solve this you need to upgrade to clang 6.
A temporay and quick workaround is possible (but not recommanded since it plays with std namespace), it could be something like:
#if defined(__clang__) && __cplusplus >= 201703L && __clang_major__ < 6
// This is a minimal workaround for clang 5.0 with missing std::byte type
namespace std {
enum class byte : unsigned char {};
}
#endif
Related
We just got burnt by a typo: "constexpr bool maxDistance=10000;"
Both gcc and clang compile this with no warning.
The real error here is that the variable shouldn't have been of type bool, but should have been an integer type instead.
How can we ensure we get a compiler warning in future?
#include <iostream>
constexpr bool number = 1234;
int main(int argc, char* argv[])
{
std::cout << number + 10000 << std::endl; // prints 10001.
return number;
}
The error here is that the variable is declared with the wrong type, however neither clang nor gcc give a warning.
gcc -Wall -std=c++14 test.cpp -lstdc++
clang -Wall -std=c++14 test.cpp -lstdc++
(using gcc 5.4.0 and clang 3.8.0)
Note: I've since learnt about a possible compile flag: -Wint-in-bool-context however this doesn't appear to be implemented in the version I'm using (5.4.0) nor in clang (3.8.0).
Is this the right way to go?
You should use direct list initialization syntax, it prohibits narrowing:
constexpr bool number{1234}; // error: narrowing conversion of '1234' from 'int' to 'bool' [-Wnarrowing]
I've discovered that gcc has a flag '-Wint-in-bool-context' however this doesn't appear to be implemented in the version I'm using (5.4.0) nor in clang (3.8.0).
Is this the right way to go?
I am compiling the code on solaris 5.11.
G++ version is 4.8.2.
The same code works on Ubuntu but gives the error: 'to_string() was not declared in this scope' on solaris.
I went through many links and tried the following things:
Adding 'std::' before to_string(). This gives error - 'to_string is not a member of std'
Added 'std=c++11' or 'std=c++0x' while compilation.
Both the above things do not work.
Is there anything related to Solaris?
The actual code was very huge. So simulating the error in sample code below.
temp.cpp
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str;
int i = 10;
str = "john age is " + to_string(i);
cout << str;
return 0;
}
command: g++ temp.cpp -std=c++0x -o temp
For GCC 4.8.2 the to_string functions are defined conditionally, according to the following:
#if ((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \
&& !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
The GLIBCXX_USE_C99 macro depends on a large number of C99 functions being supported by the OS, so presumably the necessary C99 library functions were not found when building GCC on Solaris. So the to_string definitions are absent.
In current versions of GCC the condition is more fine-grained, and checks whether the C99 functions are defined in C++98 mode and C++11, so that the absence of any C99 function doesn't disable everything:
#if __cplusplus >= 201103L
//...
#if _GLIBCXX_USE_C99_STDIO
It's not possible to backport these improvements to GCC 4.8, so you might need to update to at least GCC 6.
compile using std=c++11 as below
g++ -std=c++11 filename.cc
Note : your compiler must support c++11
Is this gcc being overly nice and doing what the dev thinks it will do or is clang being overly fussy about something. Am I missing some subtle rule in the standard where clang is actually correct in complaining about this
Or should I use the second bit of code which is basically the how offsetof works
[adrian#localhost ~]$ g++ -Wall -pedantic -ansi a.cc
[adrian#localhost ~]$ a.out
50
[adrian#localhost ~]$ cat a.cc
#include <iostream>
struct Foo
{
char name[50];
};
int main(int argc, char *argv[])
{
std::cout << sizeof(Foo::name) << std::endl;
return 0;
}
[adrian#localhost ~]$ clang++ a.cc
a.cc:10:29: error: invalid use of non-static data member 'name'
std::cout << sizeof(Foo::name) << std::endl;
~~~~~^~~~
1 error generated.
[adrian#localhost ~]$ g++ -Wall -pedantic -ansi b.cc
[adrian#localhost ~]$ a.out
50
[adrian#localhost ~]$ cat b.cc
#include <iostream>
struct Foo
{
char name[50];
};
int main(int argc, char *argv[])
{
std::cout << sizeof(static_cast<Foo*>(0)->name) << std::endl;
return 0;
}
[adrian#localhost ~]$ clang++ b.cc
[adrian#localhost ~]$ a.out
50
I found adding -std=c++11 stops it complaining. GCC is fine
with it in either version.
Modern GCC versions allow this even in -std=c++98 mode. However, older versions, like GCC 3.3.6 of mine, do complain and refuse to compile.
So now I wonder which part of C++98 I am violating with this code.
Wikipedia explicitly states that such a feature was added in C++11, and refers to N2253, which says that the syntax was not considered invalid by the C++98 standard initially, but then intentionally clarified to disallow this (I have no idea how non-static member fields are any different from other variables with regard to their data type). Some time later they decided to make this syntax valid, but not until C++11.
The very same document mentions an ugly workaround, which can also be seen throughout the web:
sizeof(((Class*) 0)->Field)
It looks like simply using 0, NULL or nullptr may trigger compiler warnings for possible dereference of a null pointer (despite the fact that sizeof never evaluates its argument), so an arbitrary non-zero value might be used instead, although it will look like a counter-intuitive “magic constant”. Therefore, in my C++ graceful degradation layer I use:
#if __cplusplus >= 201103L
#define CXX_MODERN 2011
#else
#define CXX_LEGACY 1998
#endif
#ifdef CXX_MODERN
#define CXX_FEATURE_SIZEOF_NONSTATIC
#define CxxSizeOf(TYPE, FIELD) (sizeof TYPE::FIELD)
#else
// Use of `nullptr` may trigger warnings.
#define CxxSizeOf(TYPE, FIELD) (sizeof (reinterpret_cast<const TYPE*>(1234)->FIELD))
#endif
Usage examples:
// On block level:
class SomeHeader {
public:
uint16_t Flags;
static CxxConstExpr size_t FixedSize =
#ifdef CXX_FEATURE_SIZEOF_NONSTATIC
(sizeof Flags)
#else
sizeof(uint16_t)
#endif
;
}; // end class SomeHeader
// Inside a function:
void Foo(void) {
size_t nSize = CxxSizeOf(SomeHeader, Flags);
} // end function Foo(void)
By the way, note the syntax difference for sizeof(Type) and sizeof Expression, as they are formally not the same, even if sizeof(Expression) works — as long as sizeof (Expression) is valid. So, the most correct and portable form would be sizeof(decltype(Expression)), but unfortunately it was made available only in C++11; some compliers have provided typeof(Expression) for a long time, but this never was a standard extension.
I've been learning C++ and using the Terminal for the last couple of months. My code was compiling and running fine using g++ and C++11, but in the last couple of days it started giving errors and I have had problems compiling since. The only programs I can compile and run depend on older C++ standards.
The errors I first got related to #include < array > in the header file. Not sure why this happened, but I got around it by using boost/array instead. Another error I can't solve is with std::stoi. Both array and stoi should be in the C++11 standard library. I made the following simple code to demonstrate what's going on:
//
// stoi_test.cpp
//
// Created by ecg
//
#include <iostream>
#include <string> // stoi should be in here
int main() {
std::string test = "12345";
int myint = std::stoi(test); // using stoi, specifying in standard library
std::cout << myint << '\n'; // printing the integer
return(0);
}
Try to compile using ecg$ g++ -o stoi_trial stoi_trial.cpp -std=c++11
array.cpp:13:22: error: no member named 'stoi' in namespace 'std'; did you mean
'atoi'?
int myint = std::stoi(test);
~~~~~^~~~
atoi
/usr/include/stdlib.h:149:6: note: 'atoi' declared here
int atoi(const char *);
^
array.cpp:13:27: error: no viable conversion from 'std::string' (aka
'basic_string') to 'const char *'
int myint = std::stoi(test);
^~~~
/usr/include/stdlib.h:149:23: note: passing argument to parameter here
int atoi(const char *);
^
2 errors generated.
I also get these errors at compilation when using gcc or clang++ and with -std=gnu++11 (I guess they all depend on the same file structure). I also get the same error whether I specify std:: in the code, or if I specify using namespace std;
I worry that these issues arose because of the September Command Line Tools update via Xcode or because I installed boost and this somehow messed up my C++11 libraries. Hopefully there is a simple solution.
My system:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-> dir=/usr/include/c++/4.2.1
Apple LLVM version 5.0 (clang-500.2.76) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin12.5.0
Thread model: posix
Thanks for any insight you can offer.
clang has a weird stdlib, you need to add the following flag when you compile
-stdlib=libc++
your snippet works on my mac with
g++ -std=gnu++11 -stdlib=libc++ test.cpp -o test
This answer describes the problem
I wrote the some buggy code like this:
#include "stdafx.h"
#include <string>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
string some_file = "afdfadf";
if(true)
{
string some_file = "/"+ some_file;
}
return 0;
}
It will throw an exception when calling std::operator+.
I guess this is because in the if statement the second some_file is an uninitialized string.
Is there any static checking tool that can help find this kind of bug?
I just tried, clang can help find the bug:
[~]$ clang bug.cpp
bug.cpp:11:29: warning: variable 'some_file' is uninitialized when used within
its own initialization [-Wuninitialized]
string some_file = "/"+ some_file;
~~~~~~~~~ ^~~~~~~~~
GCC has a warning for that case:
$ g++ t.cc -Wshadow
t.cc: In function ‘int main(int, char**)’:
t.cc:11:16: warning: declaration of ‘some_file’ shadows a previous local [-Wshadow]
t.cc:7:12: warning: shadowed declaration is here [-Wshadow]
Compilers can warn you about using a variable in its own initialization.
In GCC and CLANG, you can use -Winit-self
I am not sure about MSVC, but compiling with /W4 might give you a warning about those, too.
I was quit happy with using pclint. It will find this type of errors but it might take some time to configure it when used with an existing, larger code base.