gpt4 book ai didi

c++ - 指向函数和 ODR 的指针

转载 作者:可可西里 更新时间:2023-11-01 17:56:53 27 4
gpt4 key购买 nike

关于 ODR 的问题太多,但我找不到我要找的东西,如果重复或标题不合适,我们深表歉意。

考虑以下几点:

struct t {t(*id)();};

template<typename T>
t type() {return {type<T>};}

这是对我尝试定义 unique identifier per type 的过度简化。 ,希望在不同的编译单元中保持唯一。

特别是给定一个具体类型 T喜欢std::string ,并假设两个不同的编译单元在头文件中包含上述代码,我想表达

type<T>().id

在两个单元中采用相同的值(类型为 t(*)() ),因此用作类型 T 的唯一标识符.

值为函数地址 type<T> ,所以问题是是否有一个独特的功能type<T>程序中由 one-definition rule 保证. iso 3.2/3 说

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program.

哪里是 3.2/2

A non-overloaded function whose name appears as a potentially-evaluated expression or [...], is odr-used, unless [...]

我假设一个函数是非内联的,如果它的地址被占用(尽管我在标准中找不到)。

iso 3.2/5 列出了一些异常(exception)情况,但唯一对函数的引用是

inline function with external linkage, [...], non-static function template, [...], member function of a class template, or template specialization for which some template parameters are not specified [...]

这里似乎都不是这种情况。

一个可验证的例子需要多个文件。事实上,Dieter Lücking 给出了一个声称失败的例子,尽管在我的情况下它不会失败(我不将其视为任何形式的“保证”)。

那么,这是否可行?

最佳答案

所以 3.2/5 实际上似乎是一个非常强大的支持。首先请注意,定义是源代码构造,而不是目标代码构造,尽管显然两者之间存在非常密切的关系。 3.2/5 说非静态函数模板有多个定义是可以的,而且在这种情况下它必须表现得好像只有一个定义。如果一个函数在不同的翻译单元中有不同的地址,那么它的行为就好像只有一个定义,至少在我看来是这样。

这尤其正确,因为函数指针可以作为非类型模板参数传递。这些参数必须是常量,并且对于所有翻译单元都必须相同。例如,字符串文字不能恰好是这样的参数,因为它的地址因翻译单元而异。

是否满足所有要求将完全取决于多个定义的上下文,因为它们处理名称解析等事情。但是,它们都是“常规”要求属于“当然”类型。例如,违反它会是这样的:

文件1.cpp

static int i;

// This is your template.
template <typename T>
void foo() {
i; // Matches the above i.
}

文件2.cpp

static int i;

// This is your template. You are normally allowed to have multiple
// identical definitions of it.
template <typename T>
void foo() {
// Oops, matches a different entity. You didn't satisfy the requirements.
// All bets are off.
i;
}

我知道在 Linux 中通过弱符号支持多重定义。事实上,在 Linux 上,Lucking 示例之所以失败,正是因为如此。我对他要求平台的回答发表了评论。在链接时,链接器将丢弃除一个之外的所有弱符号实例。显然,如果实例实际上不相同,那将很糟糕。但是 3.2/5 中的那些要求旨在确保实例实际上都是相同的,因此链接器只能保留一个。

附录:Dieter Lucking 现在说他遇到了编译问题,而事实上他并没有失败。不过,如果熟悉 Windows DLL 内部结构的人可以在这里评论 Visual Studio 如何处理这个问题,那就太好了。

关于c++ - 指向函数和 ODR 的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23437965/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com