LINUX.ORG.RU

enum в С. конфиликты.


0

1
enum {aaa, bbb, ccc} foo;
enum {ddd, eee, aaa} bar;

foo и bar разных типов, но почему-то компилятор всё равно на второй строчке ругается на то, что aaa уже определён. Есть ли способы обойти это кроме как изменять названия?


Открываю K&R, 2.3. Константы, стр.60:

«Имена в различных перечислениях должны отличаться друг от друга.»

OldFatMan
()

Анонимус дело говорит. Вряд ли тебе нужны две константы с одинаковыми именами в одной области видимости.

schizoid ★★★
()

foo и bar разных типов

4.2

LamerOk ★★★★★
()

foo и bar разных типов, но почему-то

потому-что они одного типа. тип enum.

drBatty ★★
()

Есть ли способы обойти это кроме как изменять названия?

Нет.
Такая фича есть в C++0x:

enum class smth { fst = 1, sec, thrd, one_more };
Обращаться к полям так:
smth::fst
smth::sec
Как ты уже догадался, область видимости ограничена «smth::». А в Си мучайся...

kermzyxer
()
Ответ на: комментарий от kermzyxer

А в Си мучайся...

Есть один способ, не очень красивый, но рабочий.

const struct 
{
	int a;
	int b;
} T =
{
	.a = 0,
	.b = 1
};
LamerOk ★★★★★
()
Ответ на: комментарий от kermzyxer

А в Си мучайся...

Вы так говорите, будто это каждый день нужно.

buddhist ★★★★★
()
Ответ на: комментарий от schizoid

Ну я же могу писать

int a = 42;
char b = 42;
То есть под одной и той же константой «42» подразумевается и int и char в зависимости от контекста. А моё «aaa» так уже не может.

Ладно, ответ на вопрос я получил. Придётся тупо добавлять префиксы: foo_aaa, bar_aaa.

toady2
() автор топика
Ответ на: комментарий от toady2

42 — это число. «ааа» — это имя. Одно и то же имя не может иметь два значения одновременно.

akk ★★★★★
()

А зачем вообще именованные enum'ы определять?

И, кстати, матюги здесь из-за того, что такая запись эквивалентна:

#define aaa 1
…
#define aaa 3

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Да-да, вот это-то и больше всего раздражает. Можно спокойно написать

enum {aaa, bbb, ccc} foo;
enum {ddd, eee, fff} bar;

bar = bbb;
и компилёр даже варнингом не ругнётся.

P.S. Я вот полный ноль в С++, но просто интересно — там лучшая ситуация с enum'ами?

toady2
() автор топика
Ответ на: комментарий от toady2

А что здесь странного? Это же эквивалентно объявлению двух целочисленных переменных и уймы #define'ов, присваивающих значения макросам aaa, bbb и т.п.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от toady2

но просто интересно — там лучшая ситуация с enum'ами?

да, будет ошибка

anonymous
()
Ответ на: комментарий от anonymous

C - прекрасный язык. По крайней мере, в С однозначно понятно, во что развернется та или иная конструкция, в отличие от всяких дурацких питонов...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

А что здесь странного?

От «идеального С» я бы ожидал, что foo и bar будут считаться переменными разных типов и для каждого будет строго определёно множество возможных принимаемых значений. В частности, можно делать одинаковые имена в разных enum'ах, выдаётся ошибка на предыдущий пример и т. д.

Ну ладно С. Он вообще из каменного века и атавизмы для совместимости. С99 даже до сих пор прижить не могут. Но С++ то, по идее, должен такие штуки запросто усваивать...

toady2
() автор топика
Ответ на: комментарий от toady2

От «идеального С» я бы ожидал, что foo и bar будут считаться переменными разных типов

Это уже не идеальный С, а дрянь какая-то! Какой смысл в таком поведении?

В частности, можно делать одинаковые имена в разных enum'ах

Зачем? Можно вообще сделать один-единственный enum, в который запихать все используемые сокращения (если их не слишком много и не используются битовые маски).

Он вообще из каменного века

Лучше языка еще не придумали.

Но С++ то, по идее, должен такие штуки запросто усваивать...

А плюсы - вообще выблюдок objective-C.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

в С однозначно понятно, во что развернется та или иная конструкция

ага, если это только не очередной «undefined behavior» или платформо(компиляторо)-зависимая конструкция или декларация

anonymous
()
Ответ на: комментарий от anonymous

С какого это перепуга на C будет платформозависимая конструкция? Все платформозависимое - это уже внешние библиотеки. Так же, как и декларации (но многие из деклараций очень удобны: взять тот же openmp, к примеру).

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от anonymous

Да плевать мне. В моих велосипедах все просто, как день. И там совершенно нет места объектному ориентированию.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

С какого это перепуга на C будет платформозависимая конструкция?

facepalm.ogv

anonymous
()
Ответ на: комментарий от Eddy_Em

Это уже не идеальный С, а дрянь какая-то! Какой смысл в таком поведении?

Идеальный для меня. Надо перерегистрироваться на ник IMHO...

toady2
() автор топика
Ответ на: комментарий от Eddy_Em

Согласен.

enum {язык, зубы, рот, глаза, нос,... } часть_лица;
enum {автор, заглавие, язык, число_страниц,... } элемент_описания_книги;
enum {автор, название, версия,...} элемент_описания_программы;
хуже чем
enum {язык, зубы, рот, глаза, нос, автор, заглавие, число_страниц, название_программы, версия,...} константы_для_всего_на_свете;
и уж тем более хуже чем
#define язык 0
#define зубы 1
...
А штуки типа
if (!часть_лица) {
    printf("хватит языком чесать\n");
    элемент_описания_книги = зубы;
}
по-любому читабельнее и предпочтительнее чем
if (часть_лица == язык) {
    printf("хватит языком чесать\n");
    элемент_описания_книги = заглавие;
}

--------------------

P.S. Примеры нарошно выдуманы с чрезмерной показательностью. Просьба не комментировать фразами типа «что у тебя за прога, которая одновременно оперирует частями лица и книгами?», «какого хрена кириллица?» и т. п.

Я ведь тоже эту проблемы не из пальца высосал, а из реальной программы, что пишу сейчас. Там есть структура настроек, в которой некоторые элементы представлены enum'ами. Получилось так, что в некоторых (совсем не связанных по смыслу) enum'ах оказались константы с одинаковыми именами.

toady2
() автор топика
Ответ на: комментарий от Eddy_Em

Не. Структура это какой-то набор из нескольких переменных. А enum у меня, наоборот — одна переменная, но которая может принимать некоторый конечный набор констант.

toady2
() автор топика
Ответ на: комментарий от kermzyxer

Такая фича есть в C++0x:

Такая фича есть в обычном С++

class smth { enum{ fst = 1, sec, thrd, one_more }; };
В С++0x просто накидали сахарку.

pathfinder ★★★★
()
Ответ на: комментарий от pathfinder

В С++0x просто накидали сахарку.

Нет, там не только пространсто имён добавляется, но и исключаются неявные преобразования из/в целые.

Begemoth ★★★★★
()
Ответ на: комментарий от pathfinder
class smth { enum{ fst = 1, sec, thrd, one_more }; };

Да хорошая шутка, с class-то.

Begemoth ★★★★★
()
Ответ на: комментарий от Eddy_Em

Это уже не идеальный С, а дрянь какая-то! Какой смысл в таком поведении?

Какой смысл вообще в типах? Стоит ли вообще пытаться исключить какие-либо ошибки при компиляции программы?

Можно вообще сделать один-единственный enum

Можно вообще сделать один единственный тип - машинное слово. А нет, понадобится ещё один тип для вещественных чисел, чтобы не пришлось городить для них отдельных арифметических операторов и явных преобразований из целых чисел.

А плюсы - вообще выблюдок objective-C.

То что ты в языках программирования ты разбираешься чуть меньше, чем никак, мы в курсе.

Begemoth ★★★★★
()
Ответ на: комментарий от Eddy_Em

в С однозначно понятно, во что развернется та или иная конструкция

Почему среди недоумков так модно заниматься программированием? Cтандарт Си ни слова не говорит о том, во что развернутся твои конструкции. Со своим «пониманием» ты производишь быдлокод, который неминуемо сломается после очередной переделки gcc.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.