I switched to Linux a few days ago and I'm stuck on porting my project. For some reason, no matter if I'm using clang++ or gcc 4.8, the compiler complaints about using a atomic with a vector from the GLM-Library (something like that: atomic<glm::vec3>). I tried to set -std=c++11 and -std=gnu++11, which gcc doesn't accept and g++/clang++ don't care about. I know that it's not my code, because it worked on Windows with Visual Studio 2012.
So now my question is, if there is a good alternative to the VS2012 compiler, so that my code gets to work? I also thought to try gcc 4.9, but I really have no idea how to get that.
clang error message:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/atomic|166|error: exception specification of explicitly defaulted default constructor does not match the calculated one|
g++ error message:
/usr/include/c++/4.8/atomic|167|error: function ‘std::atomic<_Tp>::atomic() [with _Tp = glm::detail::tvec3<float>]’ defaulted on its first declaration with an exception-specification that differs from the implicit declaration ‘std::atomic<glm::detail::tvec3<float> >::atomic()’|
glm::vec3 is a typedef to some specialization of tvec<float, T>. tvec has a user-provided assignment operator, so it is not trivially copyable and therefore cannot be used with std::atomic. The code compiles with VS2012 because Microsoft's standard library implementation doesn't diagnose instantiations of std::atomic<T> for non-TriviallyCopyable T. As with any undefined behavior, the fact that it compiles does not imply that it works.
std::atomic<glm::vec3> // sizeof(...) == 12
This specialization does not exist. There are only specialization of bool, integral types and pointer types provided by the STL. Either you have to specialize it on your own, or have to use another solution for your specific problem. Please note, that std::atomic<glm::vec3> may not be TriviallyCopyable on your platform (because of the size it may nowhere be trivially copyable). This means, that a mutex is used to synchronize this. For a vector I am really sure, that there is no way to trivially copy it. So you may use a pair of vector and mutex instead.
Related
According to the standard (or at least to cppreference) the std::get for std::tuple shall:
5-8) Extracts the element of the tuple t whose type is T. Fails to compile unless the tuple has exactly one element of that type.
So I interpret that sentence such that this code does not compile:
std::tuple<int, int> my_record;
std::get<int>(my_record) = 10;
Because two identical types exist and I try to access the tuple by type. However, both GCC an Clang correctly compile this code and produce the effect of modifying the first element.
Why? Am I misinterpreting the sentence on the reference? Is the reference wrong? Do GCC and Clang not respect the standard?
Looks like a GCC 11 bug, consider filing it. Here's the revelant part of the standard.
You see it in Clang because on gcc.godbolt.org it uses GCC's standard library by default. If you add -stdlib=libc++ to use it's own standard library, it refuses to compile it.
Consider this program:
#include <iostream>
int main()
{
delete std::cout;
}
AFAIK the conversion function operator void* () const has been removed from C++11. So, this program should fail in compilation on a C++11 compiler. Ya, its true that both g++ 4.8.1 & 4.9.2 gives diagnosis (in the form of warning that deleting void* is undefined & that's also the good thing). But shouldn't this program fail in compilation because removal of that conversion function due to which all stream object could be implicitly converted to void* in C++98 & C++03?. Is this bug? It seems bit surprising that they still not have implemented this change.
I've tried this program in g++ 4.9.2(that supports C++14) but it gives warning not compiler error. Ideone compiler gives me an error as expected. (See live demo here)
It has nothing to do with the compiler, its a library issue. libstdc++ has lots of incompatibilities with C++11, of which this is just one. They are making breaking changes in 5 and up though iirc.
In short, it's neither a bug nor a compiler issue.
This is a bug in the standard library (if you view it as an implementation of the C++11/14 standard library rather than C++98/03).
It's sort of a compiler issue as well though. Specifically, removing the conversion to void * depends on adding a conversion directly to bool--but that, in turn, depends on adding "contextual conversion" to the compiler.
gcc 4.8 did implement a form of contextual conversion, but not the form that was accepted into the standard. Although the specific changes to contextual conversion wouldn't directly impact this use of contextual conversion, it does point to the fact that the definition of contextual conversion was still being tweaked as these compilers were being written.
The sequence in which things (at least normally) happen is that first the specification is solidified. Then the compiler implements it. Then the standard library puts it to use.
In this case the specification was still changing fairly shortly before the compiler was released. Therefore, the standard library didn't (and practically speaking, couldn't) use it.
By the time of 4.9, the specification was solid, and the compiler implemented the final version of contextual conversion, but it hadn't been around long enough to be put to use in the standard library yet.
I think my compiler understands C++11, but maybe not. Instead of trying it on existing messes of source code which are buggy anyway, is there some simple "hello world" level snippet of source code I can try to compile, which if it does compile without error, proves the compiler is reading it as C++11?
Try this one,
auto f = [](){};
or write some code with rvalue reference.
Shortest thing possible:
[]{};
Is's a lambda-expression without argument list.
The Problem is that compiler usually don't support a new standard completely from the start. Meaning, they may support one c++11 feature, but not another.
However, as far as c++11 is concerned, I think VC++ is the only major compiler that doesn't fully support it, even though you may have to enable the c++11 mode manually. For g++ you e.g. have to supply the compiler flag -std=c++11 (or -std=gnu++11) - the same holds true for newer versions like c++14).
Hi i have to port some stuff written on c++ from unix bases os to windows visual studio 2008.
The following code implements array data type with void ** - pointer to the data.
struct array
{
int id;
void **array; // store the actual data of the array
// more members
}
When i compile with g++ on Unix it's ok but when i try with MSVS 2008 I get the error - error C2461: 'array' : constructor syntax missing formal parameters. When i change the member from 'array' to something else it works, so it seems that the compiler thinks that the member name 'array' is actually the constructor of the struct array. It's obviously not a good practice to name the member like the struct but it's already written that way. Can i tell the MSVS compiler to ignore this problem or i should rename all members that are the same as the struct name.
You are dealing with a bug in GCC compiler. C++ language explicitly prohibits having data members whose name is the same as the name of the class (see 9.2/13). MS compiler is right to complain about it. Moreover, any C++ compiler is required to issue a diagnostic message in this case. Since GCC is silent even in '-ansi -pedantic -Wall' mode, it is a clear bug in GCC.
Revison: What I said above is only correct within the "classic" C++98 specification of C++ language. In the most recent specification this requirement only applies to static data members of the class. Non-static data members can now share the name with the class. I don't know whether this change is already in the official version of the revised standard though.
That means that both compilers are correct in their own way. MS compiler sticks to the "classic" C++98 specification of the language, while GCC seems to implement a more recent one.
I'd say that if you're doing something that you yourself describe as "not a good practice", then you should change it.
I would rename your attribute to not have the same name as the class. This will make your code more portable. If you have to move to yet another compiler in the future, you won't run in to this problem again then.
I have the following code:
typedef void VOID;
int f(void);
int g(VOID);
which compiles just fine in C (using gcc 4.3.2 on Fedora 10). The same code compiled as C++ gives me the following error:
void.c:3: error: ‘<anonymous>’ has incomplete type
void.c:3: error: invalid use of ‘VOID’
Now, this is something in external library and I would like the owner to fix that problem. So I have a question - does C++ standard forbids this construct? Could you give me a pointer/citation? The only thing I can recall is that function declaration with (void) to signal empty parameter list is deprecated in C++, but I don't understand why typedefed VOID does not work.
Yes, as far as i know the second declaration is invalid in C++ and C89, but it is valid in C99.
From The C99 draft, TC2 (6.7.5.3/10):
The special case of an unnamed parameter of type void as the only item in the list
specifies that the function has no parameters.
It's explicitly talking about the type "void", not the keyword.
From The C++ Standard, 8.3.5/2:
If the parameter-declaration-clause is empty, the function takes no arguments. The parameter list (void) is equivalent to the empty parameter list.
That it means the actual keyword with "void", and not the general type "void" can also be seen from one of the cases where template argument deduction fails (14.8.2/2):
Attempting to create a function type in which a parameter has a type of void.
It's put clear by others, notable in one core language issue report here and some GCC bugreports linked to by other answers.
To recap, your GCC is right but earlier GCC versions were wrong. Thus that code might have been successfully compiled with it earlier. You should fix your code, so that it uses "void" for both functions, then it will compile also with other compilers (comeau also rejects the second declaration with that "VOID").
gcc bugs. Edit: since it wasn't clear enough, what I meant was gcc 4.3.2 was compiling it due to bugs. See #32364 and #9278.
I just put your code in a .cpp file, and it compiled with no problems in VS2005, SUSE, Redhat, and Solaris, so I guess your specific gcc version does not approve of this.
Gal