Advertisement

Converting project code from VS13 to Code::Blocks, massive amount of errors

Started by October 15, 2014 08:53 PM
8 comments, last by SeanMiddleditch 10 years, 3 months ago

Hello.

So today i send my code/project to a friend, he uses code::blocks and i use VS13. My code compiles and runs but when he tried to build the code he is getting numerous compiler errors.

I will list one of the most occurred problem

//Visual studio 2013
void func(Vector2f & v);
func(Vector2f(10.0f, 10.0f));//Allowed in vs13, but error in code::blocks it fixed with syntax bellow
 
//Code blocks
void func(Vector2f v);
func(Vector2f(10.0f, 10.0f));

This is how i fix the error, but my question would be, can i do something not to have to fix 100+ of those errors? why doesn't code blocks compiler allow same syntax as VS does, and can i make codeBlocks allow same syntax as VS13. If not any help is appreciated.

I think even VS13 doesn't allow that code unless argument is const.

I've just tested similar situation using http://coliru.stacked-crooked.com/


void func(const int & v) {
}

int main() {
    func(5);
    return 0;
}

And it doesn't throw error.

Maybe you're missing "-std=c++11" compiler parameter? I think this kind of syntax is new one.

Advertisement
You've inadvertently relied on a horrible and well-known bug in VC++. Your code is invalid C++. GCC is very right to reject it; not only is the code wrong, it's an error _for a good reason_.

Temporaries cannot bind to lvalue references. You must use a value (as your fix did), a constant reference, or an rvalue reference. Again, this is for very good reason, and it's a bug in VC++ that your code ever worked in the first place.

For small struct types (like your two-component vector) passing by value is often as fast or faster than using a reference, at least with an up-to-date compiler using a modern ABI.

Sean Middleditch – Game Systems Engineer – Join my team!

It's not a VS bug, it's a intended (and useful) feature. It's what VS calls an extension. Unfortunately it's non standard.

There's a switch in the compiler options to turn any non standard extensions off.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Calling it an extension is marketing speak. Technically, if the compiler accepts any particular invalid code, it's an "extension." And technically, your code is still invalid.

It not a thoughtfully and intentionally added feature. It was a bug that a ton of windows code came to rely on. So now it's an "extension" because back-compat is important.

Likewise, two-phase lookup; it's a conformance bug stemming from Microsoft's unique compiler implementation that turns out to be very hard for them to fix; when it is, it'll be behind a flag as tons of code relies on the broken and non-conforming behavior. That behavior cannot be called an extension only because it breaks otherwise legal C++, otherwise they surely would call it such.

This is why you should test your code on many complete from the very start. All compilers have conformance bugs. There are many things that clang and GCC disagree on, too. They usually just fix it wheb found and break any code bad enough to rely on the incorrect behavior, though.

Sean Middleditch – Game Systems Engineer – Join my team!

You do realise that VS(Microsoft MSVS C++ compiler, in this case) and Code:blocks(GCC compiler) are different compilers? Although C++ is a standard there is a lot going on in a compiler and many tricks, bugs, lack of understanding of the standard and optimization techniques are used. Then there is lack of support(to a degree) for third party libraries like the Win32 API in GCC, and then there are all the Microsoft extensions that they add, which are not difficult to correct mainly typedefs or defines, but as said this looks like a genuine bug at the Microsoft side.
Advertisement

I think even VS13 doesn't allow that code unless argument is const.

I've just tested similar situation using http://coliru.stacked-crooked.com/


void func(const int & v) {
}

int main() {
    func(5);
    return 0;
}

And it doesn't throw error.

Maybe you're missing "-std=c++11" compiler parameter? I think this kind of syntax is new one.

I have set code::blocks compiler to use c++11 standard.

You've inadvertently relied on a horrible and well-known bug in VC++. Your code is invalid C++. GCC is very right to reject it; not only is the code wrong, it's an error _for a good reason_.

Temporaries cannot bind to lvalue references. You must use a value (as your fix did), a constant reference, or an rvalue reference. Again, this is for very good reason, and it's a bug in VC++ that your code ever worked in the first place.

For small struct types (like your two-component vector) passing by value is often as fast or faster than using a reference, at least with an up-to-date compiler using a modern ABI.

I was not aware of that.

I am just sad VS has c++ standard different then other compilers. I will probably not use it for that reason, but its a best IDE i ever used.

You do realise that VS(Microsoft MSVS C++ compiler, in this case) and Code:blocks(GCC compiler) are different compilers? Although C++ is a standard there is a lot going on in a compiler and many tricks, bugs, lack of understanding of the standard and optimization techniques are used. Then there is lack of support(to a degree) for third party libraries like the Win32 API in GCC, and then there are all the Microsoft extensions that they add, which are not difficult to correct mainly typedefs or defines, but as said this looks like a genuine bug at the Microsoft side.

I do understand its a different compiler.

It's not a VS bug, it's a intended (and useful) feature. It's what VS calls an extension. Unfortunately it's non standard.

There's a switch in the compiler options to turn any non standard extensions off.

Now that's a thing i will attempt to do, but i don't trust it any more honestly. What other stuff that's non standard does it do? I don't know and i don't want to deal with that kind of stuff, its a setback. I was aware that it shouldn't work that way, but it did, so i supposed i was wrong.

Thats not really a "genuine bug". If you turn off the MSVC extensions switch you get the correct error for the reference thing, or you can enable the relevant warning, or you can make that warning an error. There just accommodating old code by default there, because it is already hard enough to get enterprises to upgrade (and even on Linux, I had to write code for GCC 4.1 not long ago, making changes that effect old programs or code just really does not go down well).

The warning, off by default (I suppose you could argue that maybe, but some enterprises like there "treat warnings as errors" then complain about every little thing when an update breaks the build...):

warning C4239: nonstandard extension used : 'argument' : conversion from 'Vector2f' to 'Vector2f &'

If you turn extensions off entirely

error C2664: 'void func(Vector2f &)' : cannot convert argument 1 from 'Vector2f' to 'Vector2f &'

GCC has some non-standard features as well. e.g. for c++ see https://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/C_002b_002b-Extensions.html. And I recall GCC has some compliance issues as well, like two-phase-lookup not being completely perfect? Likewise Linux/GCC programmers seem to be forever depending on things from POSIX that are not actually C/C++ so porting them off of GCC/Linux is far harder than it should be, even when not dealing with GUI's, etc, so just because its a GCC compatible lib that process some data (no network,gui,drivers,etc.), in my experience can still mean that "porting is incredibly difficult"....

If you like the VS IDE then use it. IDEs can be configured to use different or multiple compilers. I'm not the one to advise you how, but I'm confident a little Google-fu will help you with it.

Now that's a thing i will attempt to do, but i don't trust it any more honestly.


Most of its standards conformance issues are just missing features.

The temporary-to-lvalue thing and two-phase lookup are the two big things that bite people transitioning compilers. I use VC++ 18 for almost all of my work without problems; porting to Clang or GCC is pretty easy afterware. Just be aware of the pitfalls and testing your code with other compilers more.

Again, even GCC and Clang have conformance issues. GCC had a _huge_ one for years where it accepted any expression that the compiler could prove was constant in all contexts that required an actual constant (an "extension" some might call it, though GCC fixed the bug after they reworked their compiler enough to be able to).

If you do all your work with a single compiler, you'll end up relying on bugs or extensions in that compiler. See the Linux kernel and the pains people have to go through to get it to compile with any compiler other than GCC, and the pain and rage that happens when GCC falters unspecified behavior that the kernel erroneously relied on (e.g., strict aliasing).

Sean Middleditch – Game Systems Engineer – Join my team!

This topic is closed to new replies.

Advertisement