GCC: __atomic_always_lock_free компилируется с -O3, но не с -O0

Образец кода:

int *s;

int foo(void)
{
  return 4;
}

int bar(void)
{
  return __atomic_always_lock_free(foo(), s);
}

Вызовы:

$ gcc t0.c -O3 -c
<nothing>

$ gcc t0.c -O0 -c
t0.c:10:10: error: non-constant argument 1 to '__atomic_always_lock_free'

Любые идеи?

Актуально: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html.

-O3 включает встраивание функций; Я подозреваю, что он встраивает foo для создания __atomic_always_lock_free(4, s), который имеет требуемый постоянный аргумент.
chepner 09.04.2022 17:29

(Более низкие уровни оптимизации не смотрят на то, что на самом деле делает foo; компилятор видит только то, что он возвращает int, и не может сказать, что это фиксированное int.)

chepner 09.04.2022 17:30
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
0
2
16
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это не кажется удивительным. В документации, на которую вы ссылаетесь, говорится, что «size должен разрешаться в константу времени компиляции», поэтому следует ожидать, что вы можете получить ошибку при передаче foo(). Однако типично, что если GCC может определить значение выражения во время компиляции, то он будет рассматривать его как константу времени компиляции, даже если оно не соответствует базовому определению языка для константного выражения. Это может считаться расширением и явно разрешено стандартом C17 в 6.6p10.

Уровень оптимизации относится к тому, что компилятор пытается вычислить выражение во время компиляции. Если оптимизация отключена, он делает немного больше, чем базовое свертывание констант, которое требует стандарт (например, 2*4). С включенной оптимизацией вы получаете преимущества полного прохода постоянного распространения, а также встраивания функций.

По сути, в -O0 компилятор не замечает, что foo() всегда возвращает одно и то же значение, потому что вы отключили оптимизацию, которая позволила бы ему прийти к такому выводу. С -O3 это так, и поэтому он принимает его как константу.

Re: «размер должен разрешаться в константу времени компиляции»: действительно! Я упустил из виду. Спасибо.

pmor 09.04.2022 18:04

Другие вопросы по теме