簡體   English   中英

__COUNTER__如何在此處導致ODR違規?

[英]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.

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