jjzjj

c++ - 头文件和 odr 中的 constexpr 全局常量

不幸的是,我对constexpr、头文件中声明的全局常量和odr感到有些困惑。简而言之:我们可以从这里得出结论吗https://isocpp.org/files/papers/n4147.pdf那个constexprMyClassconstMyClassObj(){returnMyClass{};}constexprcharconst*Hello(){return"Hello";}优于constexprMyClassconstkMyClassObj=MyClass{};constexprcharconst*kHello="Hello";用于在头文件中定义全局变量如果我想“只使用”那些全

如何避免使用特质类违反ODR

从生产库在线阅读代码时,我发现了这样的东西traits.hpptemplateclassTraits{template*=nullptr>staticvoidfoo(T&object){object.foo();}};Specialtraits.hpptemplateclassTraits{staticvoidfoo(Special&object){object.foo();}staticvoidfoo(Special&&object){object.special_foo();}};如果图书馆实例化了使用的类型,这将导致违反ODRTraits为了Something在一个翻译单元中,不包括Sp

c++ - 模板和 ODR

问题是关于C++文档和标准文档的。以下代码中是否使用了变量xodr?externintx;templateTf(){returnx;}我好像没用过,老兄文档里有写吗?(有声明,表达式中出现x是odr-use,但是......) 最佳答案 它是ODR使用的。[basic.def.odr]/2:Anexpressionispotentiallyevaluatedunlessitisanunevaluatedoperandorasubexpressionthereof.因此表达式x是潜在的求值。[basic.def.odr]/4:Avar

c++ - C++ 模块是否不存在 ODR 违规?

来自N4720C++模块草案,[basic.def.odr]/6说:[…]Foranentitywithanexporteddeclaration,thereshallbeonlyonedefinitionofthatentity;adiagnosticisrequiredonlyiftheabstractsemanticsgraphofthemodulecontainsadefinitionoftheentity.[Note:Ifthedefinitionisnotintheinterfaceunit,thenatmostonemoduleunitcanhaveandmakeuseo

c++ - 您能否通过类类型上的结构化绑定(bind)违反 ODR

如果tuple_size模板是一个完整的类型,结构化绑定(bind)特性表示它会像分解一样与元组一起使用。当std::tuple_size在程序的某一点是给定类型的完整类型而在另一点不完整时会发生什么?#include#includeusingstd::cout;usingstd::endl;classSomething{public:templateautoget(){cout(this->a);}std::tuplea{1};};namespace{autosomething=Something{};}voidfoo(){auto&[one]=something;std::get(

c++ - 有没有办法把 "inline"关键字的两种含义分开(ODR relaxation vs. function code inlining)

我想我完全理解C++中inline关键字的含义。具体来说,它意味着两个半相关的事情:对于声明为inline的函数放宽了ODR规则。因此,您可以在多个TU中定义相同的功能符号,而不会在链接它们时出现错误。这允许在header中定义函数。这是对编译器的一个建议,它应该用函数编译代码的拷贝替换函数的调用,而不是对地址的调用指令函数符号。我可以理解这两个含义在一个方向上必然相关:2必须暗示1。#2要求函数定义对所有调用该函数的TU可用。因此函数定义必须存在于多个TU中。因此需要放宽ODR以避免链接器错误。但我的问题是关于另一个方向-为什么语言设计为1必须暗示2?在某些情况下和对于某些设计决策,

c++ - 以下内容是否确实违反了 ODR?

来自here:structpiecewise_construct_t{};constexprpiecewise_construct_tpiecewise_construct={};constintmagic_number=42;inlinestd::tuplemake_magic(){returnstd::tuple(piecewise_construct,magic_number);}ThisfunctionviolatestheODR([basic.def.odr]§3.2/6)twicebecauseneitheroftheconstructor2argumentsreceive

c++ - GCC 6.3.0 中的 ODR 违规,类型定义在两个单独的翻译单元中

我们在GCC中看到了以下代码示例中的一些奇怪行为。奇怪的行为是GCC6.3.0中的ODR违规,类型定义在两个单独的翻译单元中。可能与递归类型定义或类型不完整有关。我们不确定我们的代码是否有效,或者我们是否以递归定义类型的方式依赖于未定义的行为。请查看类变体动态类模板是如何在两个单独的cpp文件中定义和实例化的。动态测试.h:#pragmaonce#include#includenamespacedynamic{templatevoiderasure_destroy(constvoid*p){reinterpret_cast(p)->~T();}templatevoiderasure_c

c++ - 是否使用静态 constexpr odr?

为什么下面的代码在gcc上有效,但在clang上却不起作用,(seeitlive):constexprintgiveMeValue(){return42;}structTryMe{staticconstexprintarr[1]={giveMeValue()};};intmain(){intval=TryMe::arr[0];returnval;}我用clang得到一个未解析的外部符号。TryMe::arr[0]是一个对象吗?如果是,是否已使用ODR? 最佳答案 TryMe::arr是odr-used但您没有提供定义(seeitli

c++ - header 中的字符串——这是否违反了 ODR?

考虑以下具有两个编译单元的程序。//a.hppclassA{staticconstchar*get(){return"foo";}};voidf();//a.cpp#include"a.hpp"#includevoidf(){std::cout//main.cpp#include"a.hpp"#includevoidg(){std::cout出于某种原因需要创建全局字符串常量是很常见的。以完全天真的方式执行此操作会导致链接器问题。通常,人们将声明放在头文件中,将定义放在单个编译单元中,或者使用宏。我的印象是这种使用函数的方式(如上所示)是“好的”,因为它是一个inline函数并且链接器