簡體   English   中英

fpermissive 標志有什么作用?

[英]What does the fpermissive flag do?

我只是想知道-fpermissive標志在 g++ 編譯器中的作用是什么? 我正進入(狀態:

錯誤:獲取臨時地址 [-fpermissive]

我可以通過將-fpermissive標志提供給編譯器來解決。

編輯:我剛剛發現導致臨時地址錯誤部分的原因。 我現在要修復那部分。

在文檔中

-fpermissive
將一些關於不合格代碼的診斷從錯誤降級為警告。 因此,使用-fpermissive將允許編譯一些不合格的代碼。

底線:除非您知道自己在做什么,否則不要使用它!

-fpermissive標志使編譯器將一些實際上是錯誤的事情(但某些編譯器允許)報告為警告,以允許代碼編譯,即使它不符合語言規則。 你真的應該解決根本問題。 發布演示問題的最小的、可編譯的代碼示例。

-fpermissive
將一些關於不合格代碼的診斷從錯誤降級為警告。 因此,使用-fpermissive將允許編譯一些不合格的代碼。

當您編寫了語言標准不允許的內容時(因此不能真正成為明確定義的行為,這是不這樣做的充分理由),但如果天真地饋送到某種可執行文件,則碰巧映射到某種可執行文件編譯引擎,然后-fpermissive將執行此操作,而不是停止並顯示此錯誤消息。 在某些情況下,該程序將完全按照您最初的預期運行,但您絕對不應該依賴它,除非您有一些非常特殊的理由不使用其他解決方案。

如果您想要一個真實的用例,請嘗試編譯一個非常舊的 X Windows 版本——比如,大約 2004 年左右的 XFree86 或 XOrg,就在拆分前后——使用 gcc 的“現代”(咳嗽)版本,如 4.9.3。

您會注意到構建 CFLAGS 指定了“-ansi”和“-pedantic”。 從理論上講,這意味着“如果有任何輕微違反語言規范的內容,就會炸毀”。 實際上,gcc 的 3.x 系列並沒有捕捉到太多這類東西,並且用 4.9.3 構建它會在地上留下一個冒煙的洞,除非你將 CFLAGS 和 BOOTSTRAPCFLAGS 設置為“-fpermissive”。

使用該標志,大多數 C 文件將實際構建,讓您可以自由移動到詞法分析器將生成的與版本相關的殘骸。 =]

存在一個簡單設置 -fpermissive 而不出汗的常見情況:經過徹底測試和工作的第三方庫,如果沒有 -fpermissive,它將無法在較新的編譯器版本上編譯。 這些庫是存在的,而且很可能不是應用程序開發人員要解決的問題,也不是在開發人員的計划預算中要做的。

設置 -fpermissive 並在這種情況下繼續。

一般的答案是它“將一些關於不合格代碼的診斷從錯誤降級為警告”。

不幸的是,我還沒有看到它允許的具體列表。

我發布答案的主要原因是建議您盡可能避免使用它。 相反,請查看每個錯誤,看看是否可以修復它。 OP 找到並修復了導致錯誤的原因。 (“獲取臨時地址”可能類似於調用返回 std::string 對象的函數,並將某些內容分配給瞬態對象的 c_ptr() 值。)

剛好在審一個項目,涉及到升級gcc的版本,開發者加了-fpermissive ,因為突然出現一堆編譯錯誤。 我注意到一項測試是:

    if (myPointer == '\0')

我指出它確實應該是:

    if (myPointer[0] == '\0')

開發人員進行了檢查,結果發現標記的每一件事都是一個真正的錯誤——其中一些已經存在了 20 多年。

正如@cli_hlt 提到的

底線:除非您知道自己在做什么,否則不要使用它!

它可以做可怕的事情,例如編譯器有時可以取消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
}

如您所見,您不能保證 map 的常量性,但是,可以保留向量或值的常量性。 PS這里我在以下編譯器中測試了GCC 12.1、9.1、8.1、7.1、6.1。 但是,clang 沒有-fpermissive 標志,它會捕獲錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM