簡體   English   中英

如何測試 _Static_assert 是否已定義?

[英]How do I test if _Static_assert is defined?

_Static_assert內置於某些 C 編譯器(例如 gcc 和 clang)中,但可能並非所有 C 編譯器都包含它。 我想使用_Static_assert功能,同時盡可能保持我的代碼跨平台。 我認為最好的方法是測試

#ifdef _Static_assert
    _Static_assert(0, "Test");
#endif

但這似乎行不通。 它編譯,但它沒有檢測到_Static_assert已定義。 然后我想我可以測試編譯器是否是 GCC,但我讀到定義__GNUC__並不一定證明使用的編譯器是 GCC。 這也不會檢測到其他我可能不知道的_Static_assert被定義的編譯器。 所以我的問題是,檢測編譯器_Static_assert在預處理器中支持_Static_assert的最佳方法是什么?

編輯:這是我想出的適合我的目的的解決方案。 感謝下面的@KamilCuk 提供幫助我的鏈接。

// Check that we can use built-in _Static_assert
#if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 201112L
    #define WE_HAVE_STATIC_ASSERT 1
#endif

#if WE_HAVE_STATIC_ASSERT
    _Static_assert(0, "Test");
#endif

這段代碼在 gcc 和 clang 上都適用於我: https : //godbolt.org/z/svaYjWj4j

最終編輯(我認為):這為我關於如何檢測_Static_assert是否可用的原始問題提供了答案。 它還提供了一個回退選項,可以在我測試的大多數編譯器中產生相對有用的錯誤。

這是測試代碼的鏈接: https : //godbolt.org/z/TYEj7Tezd

    // Check if we can use built-in _Static_assert
    #if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 201112L
        #define MY_STATIC_ASSERT(cond, msg) _Static_assert(cond, msg)
    
    #else // We make our own
        // MY_JOIN macro trick generates a unique token
        #define MY_JOIN2(pre, post) MY_JOIN3(pre, post)
        #define MY_JOIN3(pre, post) pre ## post
    
        #if defined( __COUNTER__ ) // try to do it the smart way...
            #define MY_JOIN(pre) MY_JOIN2(pre, __COUNTER__)
            #define MY_STATIC_ASSERT(cond, msg) \
            static const char *MY_JOIN(static_assert)[(cond) * 2 - 1] = { msg }
    
        #else // we did our best... 
        //will break if static assert on same line in different file
            #define MY_JOIN(pre) MY_JOIN2(pre, __LINE__)
            #define MY_STATIC_ASSERT(cond, msg) \
            static const char *MY_JOIN(static_assert)[(cond) * 2 - 1] = { msg }
        #endif
    #endif
    
    /* - CHANGE CODE HERE TO TEST THE ASSERTIONS - */
    enum {
        A = 3,
        B = 3,
        C = B - A
    };
    /* - --------------------------------------- - */
    
    // Test to see if the enum values match our assertions
    MY_STATIC_ASSERT(B > A, "B must be greater than A");
    MY_STATIC_ASSERT(C > 0, "C must be greater than zero");

我用來做這件事的有用信息來自以下鏈接:

http://jonjagger.blogspot.com/2017/07/compile-time-assertions-in-c.html

https://www.tutorialspoint.com/cprogramming/c_preprocessors.htm

https://stackoverflow.com/a/43990067/16292858

如何測試 _Static_assert 是否已定義?

_Static_assert是 C11 的一部分。 所以檢查C11。

#if __STDC_VERSION__ > 201112L

您還可以#include <assert.h>並檢查#ifdef static_assert

我第一次在 google 上搜索static_assert.h github有一個很好的例子,如何處理不同的工具和編譯器: https : //github.com/wc-duck/dbgtools/blob/master/include/dbgtools/static_assert.h#L68


如果您想編寫 C11 兼容層並在代碼中使用靜態斷言,例如使用此答案並回退到您自己的包裝器:

// static_assert.h
#define CTASTR2(pre,post) pre ## post
#define CTASTR(pre,post) CTASTR2(pre,post)
#define STATIC_ASSERT(cond) \
    typedef struct { int static_assertion_failed : !!(cond); } \
        CTASTR(static_assertion_failed_,__COUNTER__)

#include <assert.h>
#ifndef static_assert
#define static_assert(expr, str)  STATIC_ASSERT(expr)
#endif

// somefile.c
#include <static_assert.h>
static_assert(something == something, "Uwu");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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