Могу ли я отключить статические утверждения?

У меня есть несколько довольно дорогостоящих вызовов static_assert, разбросанных по моему коду. Хотя они ценны, они часто излишни и значительно увеличивают время компиляции и использование памяти.

Могу ли я отключить их?


person quant    schedule 30.10.2014    source источник
comment
Да. Удалив их.   -  person Rapptz    schedule 30.10.2014
comment
@Rapptz Как мне снова включить их?   -  person quant    schedule 30.10.2014
comment
Вы уверены, что эти static_assert вызовы несут ответственность за все эти накладные расходы?   -  person Brian Bi    schedule 30.10.2014
comment
@Brian, не все из них, но многие из них включают нетривиальные метафункции, которые вносят существенный вклад и не нужны для всех сборок.   -  person quant    schedule 30.10.2014
comment
Единственный способ отключить static_assert — это удалить их из кода, который будет скомпилирован, например, с помощью препроцессора. Они никоим образом не влияют на скомпилированный код.   -  person Deduplicator    schedule 30.10.2014
comment
На несколько «мета» ноте. Вы действительно должны начать принимать ответы. На ваши последние 20 или около того вопросов нет принятых ответов. На это обычно смотрят свысока.   -  person Rapptz    schedule 31.10.2014
comment
@Rapptz Я склонен ждать, пока не получу идеальный ответ или пока не буду уверен, что ответ настолько хорош, насколько можно сделать с учетом вопроса. Я всегда отмечаю ответы в конце концов, за очень немногими исключениями (взгляните на мою историю). Как вы думаете, это плохая практика?   -  person quant    schedule 31.10.2014


Ответы (2)


Оберните их в стандартный макрос NDEBUG.

#ifndef NDEBUG
static_assert(...);
#endif

Таким образом, для выпускных сборок вы можете отключить их, как обычные assert. Хотя смысла в этом особо не вижу.

Если вам не нравится оборачивать вызовы в макрос, вы можете определить макрос, который сделает это за вас:

#ifndef STATIC_ASSERT
#ifndef NDEBUG
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__)
#else
#define STATIC_ASSERT(...) static_assert(true, "")
#endif // NDEBUG
#endif // STATIC_ASSERT

Использование аналогично обычному static_assert. Обратите внимание, что если ваша программа определяет ключевое слово и включает стандартный заголовок библиотеки, то определение макроса static_assert является неопределенным поведением.

person Rapptz    schedule 30.10.2014
comment
Мне не особенно нравится это решение, но я думаю, что оно сработает. - person quant; 30.10.2014
comment
@quant Из-за их аспекта времени компиляции это единственный способ сделать это. Либо так, либо удалить их правильно. - person Rapptz; 30.10.2014
comment
Я действительно не рекомендую сочетать статические проверки (static_assert) с проверками во время выполнения. Если вы хотите удалить один из них, вполне возможно, что вы не хотите отключать и другие. - person Deduplicator; 30.10.2014
comment
@Deduplicator Его можно заменить любым макросом, определенным в процессе компиляции. Я просто использовал NDEBUG из-за знакомства. - person Rapptz; 30.10.2014
comment
Замена do { } while(0) не будет работать для static_assert в пространстве имен или в телах классов. - person reima; 30.10.2014
comment
@reima Хороший улов. Я не могу придумать хороший способ исправить это, кроме перемещения точки с запятой в макрос. Использование комментария, такого как /**/, просто приведет к предупреждению, которое является ошибкой с -Werror. - person Rapptz; 30.10.2014
comment
Как насчет #define STATIC_ASSERT(...) static_assert(true, "")? - person reima; 30.10.2014

  1. Вы можете либо обернуть их, каждый для себя, в свой собственный #ifdef:

    #ifndef NO_STATIC_ASSERT
    static_assert(...);
    #endif
    
  2. Или вы можете определить свой собственный STATIC_ASSERT:

    #ifndef NO_STATIC_ASSERT
        #define STATIC_ASSERT(...) /**/
    #else
      #define STATIC_ASSERT(...) static_assert(__VA_ARGS__)
    #endif
    
    • In practice, #define static_assert(...) works too, though it is UB.
  3. Или вы можете просто удалить их вручную.

Таким образом, вы можете устранить их влияние на производительность компиляции (в любом случае они никогда не влияли на производительность во время выполнения).

person Deduplicator    schedule 30.10.2014
comment
здорово, я не думал о том, что второй. Спасибо :) - person quant; 30.10.2014
comment
определение собственного макроса static_assert — поведение undefined - person Rapptz; 30.10.2014
comment
@Deduplicator Определение ключевых слов с помощью препроцессора является неопределенным поведением, если TU или заголовок включают заголовок стандартной библиотеки, что вполне вероятно. См. здесь. - person Rapptz; 30.10.2014
comment
@Дедупликатор Да. Комментарии Йоханнеса, похоже, подтверждают мои утверждения, и я ему доверяю. Тем не менее, это довольно старый и многословный спор с большой историей. - person Rapptz; 30.10.2014
comment
@Deduplicator Это в последнем черновике здесь . Однако я не хочу затягивать эту дискуссию. Обсудите это в гостиной, если хотите. - person Rapptz; 30.10.2014
comment
@Rapptz: Нет необходимости. Я поискал все остальные места, но и этого вполне достаточно. - person Deduplicator; 30.10.2014