我只是想知道 -fpermissive标志在 g + + 编译器中是做什么的:
-fpermissive
错误: 采用临时[-fpermissive ]地址
我可以通过给编译器 -fpermissive标志来解决这个问题。
编辑: 我刚刚找到了导致临时地址错误的原因! 我现在要修复这个部分。
-fpermissive旗帜使编译器报告一些实际上是错误的东西(但是有些编译器允许这样做)作为警告,以允许代码编译,即使它不符合语言规则。你真的应该解决根本的问题。发布演示问题的最小的可编译代码示例。
-fpermissive 将一些关于不一致代码的诊断从错误降级为警告。 因此,使用 -fpermissive将允许编译一些不一致的代码。
来自 那些文件:
底线: 别用它,除非你知道你在做什么!
当你写了一些语言标准不允许的东西(因此不能真正定义好行为,这是不这样做的充分理由) ,但碰巧映射到 一些类型的可执行文件,如果天真地提供给编译引擎,那么 -fpermissive就会这样做,而不是停止这个错误消息。在某些情况下,程序的行为将完全符合您最初的设想,但是您绝对不应该依赖它,除非您有一些非常特殊的理由不使用其他解决方案。
如果您想要一个真实的用例,那么可以尝试编译一个非常老的 X Windows 版本——比如,从2004年左右开始的 XFree86或 XOrg,就在拆分前后——使用“现代”(咳嗽)版本的 gcc,比如4.9.3。
您会注意到构建 CFLAGS 同时指定了“-ansi”和“-pedantic”。从理论上讲,这意味着“如果有任何东西稍微违反了语言规范,就会爆炸”。实际上,3.x 系列的 gcc 并没有捕捉到很多这样的东西,并且用4.9.3构建它将在地面上留下一个冒烟的洞,除非你将 CFLAGS 和 BootSTRAPFLAGS 设置为“-fpermissive”。
使用这个标志,这些 C 文件中的大多数将实际构建,让您可以自由地转移到 lexer 将生成的依赖于版本的残骸。=]
简单地设置-fpermissive 并且不使用它存在的一个常见情况是: 经过彻底测试和工作的第三方库,如果没有-fpermissive,就不能在较新的编译器版本上编译。这些库的存在,很可能不是应用程序开发人员要解决的问题,也不在开发人员的计划预算中。
在这种情况下,放任自流,继续前进。
一般的答案是,它“将一些关于不一致代码的诊断从错误降级为警告。”
不幸的是,我还没有看到它允许的具体清单。
我发布答案的主要原因是建议你尽可能避免使用它。相反,查看每个错误,看看是否可以修复。OP 发现并修复了导致他们错误的原因。(“获取临时对象的地址”可以类似于调用返回 std: : string 对象的函数,并为临时对象的 c _ ptr ()值赋值。)
我刚刚回顾了一个涉及到升级 gcc 版本的项目,开发人员添加了 -fpermissive,因为突然出现了一堆编译错误。我注意到一个测试是:
if (myPointer == '\0')
我指出,它真的应该是:
if (myPointer[0] == '\0')
开发人员检查后发现,每一个标记的东西都是一个真正的错误——其中一些已经存在了超过20年。
就像@cli _ hlt 提到的
底线: 不要使用它,除非你知道你在做什么!
它会做一些可怕的事情,比如编译器有时会取消 std::map变量的常量:
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 }
正如您所看到的,您不能保证映射的常量,但是,向量或值的常量可以被保留。 另外,我在下面的编译器中测试了 GCC 12.1,9.1,8.1,7.1,6.1。 但是,clang 不允许标记 拿着这个,它会捕获错误。