Должны ли компиляторы игнорировать неиспользуемые переменные, которые приводят к запуску конструкторов или деструкторов?

У меня есть код, который я вставил в деструктор, чтобы убедиться, что он запускается как при обычном выходе, так и при разматывании стека исключений:

struct withProtectedClose {

~withProtectedClose() {
// Do some cleanup here...
}
};

void test() {
withProtectedClose close;

// Do some work before closing
}

Тем не менее, компилятор g ++ (g ++ (GCC) 3.4.6 20060404 (Red Hat 3.4.6-11)) жалуется:

test.cpp: In function `void test()':
test.cpp:28: warning: unused variable 'close'

Я могу заставить его замолчать, как-то ссылаясь на переменную, но это запутывает код только для того, чтобы заставить замолчать компилятор, а не то, как я хочу, чтобы мой код оказал влияние.

Разве факта наличия деструктора не должно быть достаточно, чтобы понять компилятор в том, что нет никакой разницы в том, что переменная не используется после конструирования?

Предполагая, что компилятор не может быть закрыт при получении уведомлений о допустимых неиспользуемых переменных, есть ли способ заставить его замолчать, только не используя его?

3

Решение

Я склонен думать, что это ошибка в компиляторе. Это все еще присутствует в g ​​++ 4.7.1.

В качестве обходного пути вы можете попытаться определить конструктор, который ничего не делает. Это подавляет предупреждение с g ++ 4.7.1, я не знаю с 3.4.6.

2

Другие решения

Поскольку это кажется исключительно проблемой GCC, вы можете «исправить» ее, объявив свою структуру следующим образом:

struct __attribute__ ((__unused__)) withProtectedClose

Это надежно отключает предупреждение на моем компиляторе версии 4.6.3 (и деструктор явно запускается в соответствии со стандартом). Это будет однако еще предупредить вас о неиспользуемых переменных в противном случае.

В большинстве случаев это ошибка, о которой вы действительно хотите знать, поэтому отключите предупреждение (-Wno-unused-variable) в целом не очень хорошая альтернатива. Если по какой-либо другой причине вам захочется удалить (неумышленно) неиспользуемые переменные, потому что они вводят в заблуждение людей, читающих код, и создают ненужную нагрузку для оптимизатора.

Если вам нужно быть переносимым, используйте макрос для инкапсуляции содержимого атрибута (пустой макрос в не-GCC).

Для решения актуального вопроса «Должны ли компиляторы игнорировать неиспользуемые переменные, которые приводят к запуску конструкторов или деструкторов?» — Нет.

Стандарт C ++ гласит [3.7.3.3]:

Если переменная с автоматическим хранением имеет инициализацию или деструктор
с побочными эффектами, он не должен быть устранен, даже если он не используется,
за исключением того, что объект класса или его копирование / перемещение могут быть исключены, как указано в 12.8.

Насколько компилятор не разрешено игнорировать переменная. Однако разрешено предупреждать о чем-то, что часто непреднамеренно.

1

MSVC не выдает это предупреждение в таком случае. Если ваша версия gcc делает, попробуйте подавить это следующим образом:

withProtectedClose close;
(close);
0
По вопросам рекламы [email protected]