What does the fpermissive flag do?
Asked Answered
S

7

156

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.

Strode answered 12/1, 2012 at 23:21 Comment(0)
Z
175

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!

Zoon answered 12/1, 2012 at 23:24 Comment(6)
I expect more information than quote manual + "don't use it until you know what you are doing" from the highest voted answer. I don't have to google for this. Which cases of nonconformant code are downgraded exactly?Fidellia
Not nonconformant code is downgraded, but diagnostics is from errors to warnings. An example is given by the question opener. If you don't know what the edge cases could be, you should not consider using it.Zoon
Sorry man, no offense, but advice like "don't do something if you don't know the implications" is trivial and fits to every question and does not answer any.Fidellia
.. and sorry, but just quoting the manual without elaborating at all is not helpful. Especially in a case where the manual is very sparse.Fidellia
@Fidellia I think a good rule of thumb is, if (A) you think you "know what you're doing", (B) the behavior is defined, (C) you ran it under a test harness, and (D) nothing bad happened, you probably know what you're doing.Padre
This is indeed not helpful at all. Anyone can look up an article. A lot of flags change things from errors to warnings or vice versa. Are they all the same? What is the difference? And then just adding "Don't use it unless you know what you're doing" is also not helpful at all. Why shouldn't they? Maybe if there was more information given, people would understand why they shouldn't. Now it's just like a parent telling you not to do something without telling you why. It doesn't teach anything.Admirable
E
74

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.

Evertor answered 12/1, 2012 at 23:24 Comment(0)
E
23

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.

Edwards answered 12/1, 2012 at 23:32 Comment(1)
Something that isn't allowed by the language standard can still be well defined. In fact almost every compiler has well defined extensions. Not saying this is the case with with all instances of permissive thoughKex
I
17

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. =]

Innate answered 29/7, 2016 at 5:14 Comment(0)
B
4

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.

Bury answered 24/12, 2020 at 3:51 Comment(1)
Last time I encountered one of these, the library worked by accident and really was accessing uninitialized memory and found out later that it crashed on a Mac.Anyone
M
1

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.

Mohr answered 14/6, 2022 at 19:47 Comment(0)
N
0

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.

Nial answered 12/8, 2022 at 7:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.