LINUX.ORG.RU

compile-time проверка наличия одинаковых enum'ов

 , ,


1

2

Приветствую, есть enum вот такого вида:

enum ids {
   ID1 = 1,
   ID2 = 2,
   ID3 = 3,
};

Нужно добавить проверку этапа компиляции на предмет наличия одинаковых enum-ов, например:

enum ids {
   ID1 = 1,
   ID2 = 2,
   ID3 = 3,
   ...
   ID100 = 2
};

Можно ли это сделать макросом? Спасибо.

★★

Можно ли это сделать макросом?

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

А можно просто выучить, наконец, язык, которым пользуешься:

enum ids
{
   ID1 = 1,
   ID2, /* = ID1+1 == 2 */
   ID3, /* = ID2+1 == 3 */
   ...
   ID100 /* = ID99+1 == 100 */
};
LamerOk ★★★★★
()

Ручная инициализация emun-ов для того и сделана, что вы знаете, зачем указываете дублирующие значения. Так что решение будет зависеть от того, в каком статусе это дублирование, ибо если автомат, то и не прописывайте значения, а если не автомат, то именованными константами/статическими макросами и инициализируйте.

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

Ручная инициализация emun-ов для того и сделана, что вы знаете, зачем указываете дублирующие значения.

При ручной инициализации легко сделать опечатку и создать дубль.

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

мне нужен чистый C

boost::preprocessor работает и в языке C

PS «чистый» C - это как сказать «мне нужен чистый паскаль», увидя ссылку на фортрановские либы) C и C++ - разные языки, так-то

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

При ручной инициализации легко сделать опечатку и создать дубль.

А как компилятору понять, вы описались или так и было задумано? Ну можно сделать тупой switch, если не можете не делать опечатки, но тогда вам надо компилировать два раза, второй раз выключать эту тупизну, чтобы в объектник не попало.

switch(i) {
        case ID1: break;
        case ID2: break;
        case ID100: break;
        }

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

Сомневаюсь что boost::preprocessor допустят в ядро, поэтому мне нужно решение на чистом C.

«чистом» как слеза младенца?) или на помытом С?)

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

А можно полностью пример? Судя по http://stackoverflow.com/a/21379862 , там все-таки придется как-то изменять определение этого enum'a. Ну и в целом выглядит адовенько.

cruz7, это можно сделать пре-препроцессором. Крутость решения в том что не нужно вообще ничего модифицировать. Некрутость в том что нужно запускать gccxml и парсить его вывод.

$ gccxml my_cool_prog.c -o check.xml

Парсер xml-результата:

#!/usr/bin/env python

import xml.etree.ElementTree
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('file', type=argparse.FileType('r'))
args = parser.parse_args()

e = xml.etree.ElementTree.parse(args.file).getroot()

for enums in e.findall('Enumeration'):
    print('Enum {}, line {}'.format(enums.get('name'), enums.get('line')))
    enum_items_dict = {}
    for enum_items in enums.findall('EnumValue'):
        for name, init in enum_items_dict.iteritems():
            if init == enum_items.get('init'):
                print(' Duplicate value of {} and {}: {}'.format(enum_items.get('name'), name, init))
        enum_items_dict[enum_items.get('name')] = enum_items.get('init')

$ ./check.py check.xml
Enum ids, line 9
 Duplicate value of ID100 and ID2: 2
Deleted
()
Ответ на: комментарий от Deleted

там все-таки придется как-то изменять определение этого enum'a.

ну без этого никуда, в новом стандарте цпп эта проблема решается, возможно будет решение и в новом стандарте для си

Крутость решения в том что не нужно вообще ничего модифицировать. Некрутость в том что нужно запускать gccxml и парсить его вывод.

ну вы читер =) так-то можно что угодно в compile-time проверить)

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

так-то можно что угодно в compile-time проверить)

Ну так и проверяйте ;)
ИМХО, это самый просто и безопасный способ.

joy4eg ★★★★★
()

Можно добавить самописный проход в clang

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