[sisyphus] liblensfun vs g++

Sergey Vlasov vsu на altlinux.ru
Ср Авг 19 12:27:44 MSD 2009


On Wed, Aug 19, 2009 at 04:41:07AM +0400, Dmitry V. Levin wrote:
> Поведение g++ изменилось между 4.3 и 4.4; если это не regression, то, видимо,
> надо патчить liblensfun (см. патч).

Testcase попроще:

-----------------------------------------------------------------------
#include <stdio.h>

enum TestEnum
{
	TEST_0,
	TEST_1
};

#ifndef __cplusplus
typedef enum TestEnum TestEnum;
#endif

#ifdef __cplusplus
extern "C"
#endif
void print_value(TestEnum x)
{
	switch (x) {

	  case TEST_0:
		printf("TEST_0\n");
		return;

	  case TEST_1:
		printf("TEST_1\n");
		return;
	}
	printf("BAD\n");
}

int main(int argc, char *argv[])
{
	(void)argc; (void)argv;

	print_value(TEST_0);
	print_value(TEST_1);
	print_value((TestEnum)2);
	return 0;
}
-----------------------------------------------------------------------

При компиляции этого кода как C он работает ожидаемым образом:

$ gcc -g -O2 -Wall -W -o enum_test enum_test.c     
$ ./enum_test                                 
TEST_0
TEST_1
BAD

А вот при компиляции как C++ происходит странное:

$ g++ -g -O2 -Wall -W -o enum_test enum_test.c     
$ ./enum_test                                 
TEST_0
TEST_1
TEST_0

(и даже с -O0 этот результат не меняется).

Формально стандартом C++98 подобное поведение не запрещено - результат
преобразования целочисленного значения в enum-тип не определён в
случае, когда значение не входит в диапазон значений этого enum:

  5.2.9/7:
    A value of integral type can be explicitly converted to an
    enumeration type. The value is unchanged if the integral value is
    within the range of the enumeration values (7.2). Otherwise, the
    resulting enumeration value is unspecified.

(причём для "unspecified behavior" не обязательно даже документировать
поведение в таких случаях).

С точки зрения C++98 ошибочный код в данном случае - (TestEnum)2;
в комбинации ufraw+liblensfun ситуация усугубляется тем, что
преобразование в enum выполняется в коде на C, для которого enum
практически не отличается от целочисленного типа.

Что интересно - такое поведение компилятора наблюдается только для
enum с двумя константами; при добавлении третьей константы проверки на
недопустимое для enum значение не исчезают.
----------- следующая часть -----------
Было удалено вложение не в текстовом формате...
Имя     : отсутствует
Тип     : application/pgp-signature
Размер  : 197 байтов
Описание: Digital signature
Url     : <http://lists.altlinux.org/pipermail/sisyphus/attachments/20090819/b4dca6de/attachment.bin>


Подробная информация о списке рассылки Sisyphus