[英]How can __COUNTER__ cause a ODR-violation here?
在此演示在大約0時19分○○秒,安德烈Alexandrescu的解釋他的執行SCOPE_EXIT
宏。 他在堆棧上創建一個ScopeGuard
對象,在銷毀時執行lambda:
#define ANONYMOUS_VARIABLE(str) \
CONCATENATE(str, __COUNTER__)
namespace detail {
enum class ScopeGuardOnExit {};
template <typename Fun>
ScopeGuard<Fun>
operator+(ScopeGuardOnExit, Fun&& fn) {
return ScopeGuard<Fun>(std::forward<Fun>(fn));
}
}
#define SCOPE_EXIT \
auto ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE) \
= ::detail::ScopeGuardOnExit() + [&]()
到目前為止,眾所周知(他甚至在他的幻燈片中說這是一頂舊帽子)。 用法如下:
void foo()
{
SCOPE_EXIT{ printf("foo exits"); };
}
但是在01:04:00,Chandler Carruth聲稱使用__COUNTER__
宏來創建“匿名”名稱會__COUNTER__
聯函數中使用時導致ODR違規。 這可能是真的嗎? 該宏僅用於創建局部變量名稱,而不是類型名稱或其他內容,因此如何導致ODR違規?
假設內聯函數位於包含在兩個不同轉換單元中的標題中,並且計數器的值恰好在每個轉換單元中具有不同的值。
然后,您有兩個內聯函數的定義,它們具有不同的變量名稱。 這是ODR違規 - 您必須為每個定義使用相同的令牌序列。
(雖然在實踐中,如果它引起任何問題,我會非常驚訝。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.