What does the fpermissive flag do? - c++

I'm just wondering what the -fpermissive flag does in the g++ compiler? I am getting:
error: taking address of temporary [-fpermissive]
which I can solve by giving the -fpermissive flag to the compiler.
EDIT:
I just found what was causing the temporary address error part! I'm going to fix that part right now.

Right from the docs:
-fpermissive
Downgrade some diagnostics about nonconformant code from errors to warnings.
Thus, using -fpermissive will allow some nonconforming code to compile.
Bottom line: don't use it unless you know what you are doing!

The -fpermissive flag causes the compiler to report some things that are actually errors (but are permitted by some compilers) as warnings, to permit code to compile even if it doesn't conform to the language rules. You really should fix the underlying problem. Post the smallest, compilable code sample that demonstrates the problem.
-fpermissive
Downgrade some diagnostics about nonconformant code from errors to warnings.
Thus, using -fpermissive will allow some nonconforming code to compile.

When you've written something that isn't allowed by the language standard (and therefore can't really be well-defined behaviour, which is reason enough to not do it) but happens to map to some kind of executable if fed naïvely to the compiling engine, then -fpermissive will do just that instead of stopping with this error message. In some cases, the program will then behave exactly as you originally intended, but you definitely shouldn't rely on it unless you have some very special reason not to use some other solution.

If you want a real-world use case for this, try compiling a very old version of X Windows-- say, either XFree86 or XOrg from aboout 2004, right around the split-- using a "modern" (cough) version of gcc, such as 4.9.3.
You'll notice the build CFLAGS specify both "-ansi" and "-pedantic". In theory, this means, "blow up if anything even slightly violates the language spec". In practice, the 3.x series of gcc didn't catch very much of that kind of stuff, and building it with 4.9.3 will leave a smoking hole in the ground unless you set CFLAGS and BOOTSTRAPCFLAGS to "-fpermissive".
Using that flag, most of those C files will actually build, leaving you free to move on to the version-dependent wreckage the lexer will generate. =]

A common case for simply setting -fpermissive and not sweating it exists: the thoroughly-tested and working third-party library that won't compile on newer compiler versions without -fpermissive. These libraries exist, and are very likely not the application developer's problem to solve, nor in the developer's schedule budget to do it.
Set -fpermissive and move on in that case.

The general answer is that it "Downgrades some diagnostics about nonconformant code from errors to warnings."
Unfortunately, I haven't seen a specific list of things that it allows.
My main reason for posting an answer is to suggest that you avoid using it if at all possible. Instead, look at each error and see if it can be fixed. OP found and fixed what was causing their error. ("taking address of temporary" could be something like calling a function that returns a std::string object, and assigning something to the transient object's c_ptr() value.)
I was just reviewing a project that involved upgrading the version of gcc, and the developer added -fpermissive because there were suddenly a bunch of compilation errors. I noticed that one test was:
if (myPointer == '\0')
I pointed out that it really should be:
if (myPointer[0] == '\0')
The developer checked, and it turned out that every single thing flagged was a real error - some of which had been present for over 20 years.

As #cli_hlt mentioned
Bottom line: don't use it unless you know what you are doing!
It can do horrible things such that a compiler sometimes can cancel of constness of variables for std::map:
#include <map>
#include <vector>
#include <iostream>
#include <string>
struct B{
std::map<std::string, int> m_map;
std::vector<int> m_vector;
B(){
m_map["a"] = 1;
m_map["b"] = 2;
m_map["c"] = 3;
m_vector.emplace_back(1);
m_vector.emplace_back(2);
m_vector.emplace_back(3);
}
const std::map<std::string, int>& getMap() const {
return m_map;
}
const int& getMapValue(const std::string& key) const {
return m_map.at(key);
}
const std::vector<int>& getVector() const {
return m_vector;
}
const int& getVectorValue(const int& i) const {
return m_vector[i];
}
};
int main(){
B b;
auto& my_map = b.getMap(); // we get const ref here
my_map["a"] = 10; // here we can modify it
std::cout << "my_map[a]=" << my_map.at("a") << std::endl;
auto& my_map2 = b.getMap(); // here we return already modified variable
std::cout << "my_map2[a]=" << my_map2.at("a") << std::endl;
auto& my_value = b.getMapValue("b");
// my_value = 20; // compiler error
// std::cout << "my_map[b]=" << my_value << std::endl;
auto& my_vector = b.getVector();
// my_vector[0] = 10; // compiler error
// std::cout << "my_vector[0]=" << my_vector[0] << std::endl;
const int a = 10;
auto& a1 = a;
// a1 = 100; // compiler error
}
As you can see you can't guarantee the constness of the map, however, the constness of a vector or value can be preserved.
P.S. here I tested in the following compilers GCC 12.1, 9.1, 8.1, 7.1, 6.1.
However, clang does not -fpermissive flag have this and it will catch the error.

Related

c++ code behaves abnormally when the return value is missing

GCC 9.2.1 gives a warning that there is "no return statement in function returning non-void", however, the code does compile (I compiled with flags -O3 and -finline-functions).
I expected the program to have no output, as the condition for the while loop should evaluate to false. However, I got the following output from the program (printed in the while loop):
"it != mMap.end(): 0"
The output is particularly odd, given that the printed value (i.e., 0 or "false") is also the condition for the while loop.
After the print, the program segfaults because the iterator becomes invalid (via it++ in the while loop that should never have executed).
I guess this can all be chalked up to the missing return value. But, I find it surprising that the code behaves so pathologically simply because a return value isn't supplied. I'd appreciate any insight into understanding what's happening at a deeper level.
#include <iostream>
#include <tr1/unordered_map>
struct Test
{
int Dummy (void) const
{
std::tr1::unordered_map<int, int>::const_iterator it = mMap.begin();
while (it != mMap.end())
{
std::cout << "it != mMap.end(): " << (it != mMap.end()) << std::endl;
it++;
}
}
std::tr1::unordered_map<int, int> mMap;
};
int main (void)
{
Test test;
test.Dummy();
return 0;
}
Returning from a non-void function without supplying a return value is underfined behavior, and therefore the compiler can do whatever it wants.
What the compiler has done in this case in particular, seems to be that it has spotted that skipping the loop would trigger UB and therefore assumes the loop is entered at least once. Therefore it assumes that it can safely enter the loop without checking the condition as the compiler trusts that the author of the program did not invoke any undefined behavior.
This is of course speculation from my part.
You should turn on warnings using -Wextra and -Wall in gcc which will e.g. enable the warning Control reaches the end of a non-void function so you will hopefully not forget about fixing stuff like that. To enforce it, enable the compiler flag -Werror.
Not returning a value invokes undefined behavior so the compiler is allowed to either return a garbage value or crash your program (this is what clang typically does) if the function returns. This is bad and you should never keep broken code like that. For additional insight you can use a disassembler and see what your compiler did at the end of the function.

c++ casting for different targets (compilers)

Given the following:
code-link
Here is the code itself for convenience (and I am not sure my link is working):
#include <iostream>
#include <vector>
#include <stdint.h>
using namespace std;
int main()
{
cout<<"Hello World";
std::vector<std::string> test_vect {"1", "2"};
long unsigned int size = static_cast<long unsigned int>(test_vect.size());
std::cout << "size: " << size << std::endl;
return 0;
}
And the following compile options: g++ file.c -Wall -Wextra "-Werror" "-Wuseless-cast"
You can see here that I am casting vector.size() to long unsigned int, this gets flagged up as a useless cast on Wandbox (my link) however the same code running on my linux box does not give a warning - but it will give me a different warning if I dont cast it.
I understand that the two unsigned long vs size_t can be different. But what I am trying to do is write some code that has no warnings with all the casting warnings set (maybe this is optamisitic when cross compiling).
So, one compiler complains that I am converting types, so I cast, but then another compiler is complaining about useless cast - so I remove the cast - and around we go :(
Is there a good approach to this so that I dont get warnings on either compilers?
I was going to just remove the -Wuseless-cast option, but I thought I would see if anyone has other ideas...
what I am trying to do is write some code that has no warnings with all the casting warnings set (maybe this is optamisitic when cross compiling)
It's optimistic when cross compiling if you have casts.
Is there a good approach to this so that I dont get warnings on either compilers?
Don't have casts. Make your variable be of type std::size_t.
I was going to just remove the -Wuseless-cast option
That's the other option.
As Lightness Races in Orbit pointed out, size_t is an option, it should have an appropriate macro to make compilers happy, if you somehow don't want to use that - making your variable auto or decltype(test_vect.size()) would be another option:
auto size = test_vect.size();
or
decltype(test_vect.size()) size = test_vect.size();
One argument that comes to mind is: Why does your size variable need to be long unsigned at all instead of std::size_t?
Just in case there is a compelling reason for that, how about (C++17):
long unsigned size;
if constexpr(sizeof(long unsigned)!=sizeof(std::size_t))
size = static_cast<long unsigned>(...);
else
size = ...;

Why doesn't Visual Studio fire a warning at self-assignment (int foo = foo;)

I was refactoring a term which appeared a bazilion times when by accident I produced a situation like in the code below:
#include "stdafx.h"
#include <iostream>
int foo = foo;
//By replacing with the following instruction we causes a compile error
//int foo(foo);
int _tmain(int argc, _TCHAR* argv[])
{
int bar = bar;
std::cout << "Well this is awkward " << foo << std::endl;
return 0;
}
With different debug and release configurations the compiler is silent about int foo = foo;.
I fail to see a situation where this statement is not a bug waiting to happen. Shouldn't the Visual Studio compiler fire a warning?
I am not pretending this is an undefined behavior. I am saying that by default making an assignment from a variable to itself is likely to be the programmer mistake. Unless someone has a weird scheme around the use of the assignment operator.
A similar issue (i=i++) is indeed undefined behavior, but it's mainly because the instruction contains two assignments to the same variable:
The incrementing of i (i++), which is done at some point after the instruction i++ returns i
The assignment of i
The problem is that we can't really know if the assignment of i happens before or after incrementing, thus undefined behavior.
In your example, foo=foo, we have a read, followed by a write. Unambiguously, we will have to read the value before writing to it, so it's easy to define.
A side note is that if operator= is redefined, then foo=foo could do a lot of things that aren't simply a copy of foo into itself. C++ purposefully allows you to shoot yourself in the food in many different ways. But in any case C++ compilers are not the gold standard of pro-activeness in warnings/errors.

Why are (member) function pointers behaving so weirdly in Visual C++?

I've had a really bizarre problem that I've reduced to the following test case:
#include <iostream>
#include <map>
#include <string>
struct Test
{
std::map<std::string, void (Test::*)()> m;
Test()
{
this->m["test1"] = &Test::test1;
this->m["test2"] = &Test::test2;
}
void test1() { }
void test2() { }
void dispatch(std::string s)
{
if (this->m.at(s) == &Test::test1)
{ std::cout << "test1 will be called..." << std::endl; }
else if (this->m.at(s) == &Test::test2)
{ std::cout << "test2 will be called..." << std::endl; }
(this->*this->m.at(s))();
}
};
int main()
{
Test t;
t.dispatch("test1");
t.dispatch("test2");
}
It outputs
test1 will be called...
test1 will be called...
when optimizations are enabled, which is really bizarre. What's going on?
This is a by-product of what Visual C++ refers to as Identical COMDAT Folding (ICF). It merges identical functions into a single instance. You can disable it by adding the following switch to the linker commandline: /OPT:NOICF (from the Visual Studio UI it is found under Properties->Linker->Optimization->Enable COMDAT Folding)
You can find details at the MSDN article here: /OPT (Optimizations)
The switch is a linker-stage switch, which means you won't be able to enable it just for a specific module or a specific region of code (such as __pragma( optimize() ) which is available for compiler-stage optimization).
In general, however, it is considered poor practice to rely on either function pointers or literal string pointers (const char*) for testing uniqueness. String folding is widely implemented by almost all C/C++ compilers. Function folding is only available on Visual C++ at this time, though increased widespread use of template<> meta-programming has increased requests for this feature to be added to gcc and clang toolchains.
Edit: Starting with binutils 2.19, the included gold linker supposedly also supports ICF, though I have been unable to verify it on my local Ubuntu 12.10 install.
It turns out Visual C++'s linker can merge functions with identical definitions into one.
Whether that's legal or not according to C++, I have no idea; it affects observable behavior, so it looks like a bug to me. Someone else with more information may want to chime in on that though.
C++11 5.3.1 describes what & does; in this instance, it gives you a pointer to the member function in question, and the passage makes no requirement that this pointer must be unique.
However, 5.10/1 says about ==:
Two pointers of the same type compare equal if and only if they are both null, both point to the same function, or both represent the same address.
The question then becomes... are test1 and test2 "the same function"?
Though the optimizer has collapsed them into a single definition, arguably the two names identify two functions and, as such, this would seem to be an implementation bug.
(Note, though, that the VS team don't care and consider it "valid enough" to warrant the benefits of the optimisation. That, or they don't realise that it's invalid.)
I'd stick to using the strings as "handles" for your function pointers.

Is it legal to switch on a constant in C++?

I was just made aware of a bug I introduced, the thing that surprised me is that it compiled, is it legal to switch on a constant?
Visual Studio 8 and Comeau both accept it (with no warnings).
switch(42) { // simplified version, this wasn't a literal in real life
case 1:
std::cout << "This is of course, imposible" << std::endl;
}
It's not impossible that switching on a constant makes sense. Consider:
void f( const int x ) {
switch( x ) {
...
}
}
Switching on a literal constant would rarely make sense, however. But it is legal.
Edit: Thinking about it, there is case where switching on a literal makes
perfect sense:
int main() {
switch( CONFIG ) {
...
}
}
where the program was compiled with:
g++ -DCONFIG=42 foo.cpp
Not everything that makes sense to the compiler makes sense!
The following will also compile but makes no sense:
if (false)
{
std::cout << "This is of course, imposible" << std::endl;
}
It's up to us as developers to spot these.
One good reason for this being legal is that the compiler might well be able to resolve the value at compile time, depending on what stage of development you're at.
E.g. you might use something like this for debugging stuff:
int glyphIndex;
...
#if CHECK_INVALID_GLYPH
glyphIndex = -1;
#endif
switch (glyphIndex)
...
The compiler knows for certain that glyphIndex is -1 here, so it's as good as a constant. Alternatively, you might code it like this:
#if CHECK_INVALID_GLYPH
const int glyphIndex = -1;
#else
int glyphIndex = GetGlyph();
#endif
You wouldn't really want to have to change the body of your switch statement just so you could make little changes like this, and the compiler is perfectly capable of rationalising the code to eliminate the parts that will never be executed anyway.
Yes, it's perfectly legal to switch on any integer expression. It's the same as switching on an integer value returned by a function - a construct used quite often.
Yes, but why you'd want to (unless debugging) is another matter.
It's similar to if (0) or while (true).
Yes, it's legal.
​​​​​​​​​​​​​​