[C] В чём маза #define A A ?
Наверное, в том, что #ifdef начнёт работать.
---
...Я работаю антинаучным аферистом...
---
...Я работаю антинаучным аферистом...
для таких случаев пишут так:
сравни с _SIZE_T_DEFINED, _WCHAR_T_DEFINED, _FILE_DEFINED и т.п. (я смотрю в stdio.h от MSVC 6.0 [cl v12.00.8168, от 1998 года] )
Зачем переопределять константы enum-ов?
#define _MY_TYPE_DEFINED_
enum MyType {
A = 1,
#define A A
B = 2,
#define B B
C = 3,
#define C C
D = 4,
#define D D
...
};
....
#ifdef _MY_TYPE_DEFINED_
...
#endif
сравни с _SIZE_T_DEFINED, _WCHAR_T_DEFINED, _FILE_DEFINED и т.п. (я смотрю в stdio.h от MSVC 6.0 [cl v12.00.8168, от 1998 года] )
Зачем переопределять константы enum-ов?
а в каком файле ты такое встречаешь? Может быть, енум в разных версиях может содержать разные значения, и хочется иметь по дефайну на каждое?
/usr/include/bits/fenv.h
/usr/include/bits/confname.h
ну и т.д. почти все файлы в каталоге bits
как оно может быть разное, если явно указано его значение?
/usr/include/bits/confname.h
ну и т.д. почти все файлы в каталоге bits
как оно может быть разное, если явно указано его значение?
enum
{
FE_INVALID = 0x01,
#define FE_INVALID FE_INVALID
__FE_DENORM = 0x02,
FE_DIVBYZERO = 0x04,
#define FE_DIVBYZERO FE_DIVBYZERO
FE_OVERFLOW = 0x08,
#define FE_OVERFLOW FE_OVERFLOW
FE_UNDERFLOW = 0x10,
#define FE_UNDERFLOW FE_UNDERFLOW
FE_INEXACT = 0x20
#define FE_INEXACT FE_INEXACT
};
Что за файлы, я, честно говоря, не знаю. В Юниксах я лох.
Просто, может быть, пользователь может подгружать разные версии хедеров. И не хочет разбираться, что данный конкретный хедер объявляет, а что нет. Захочет воспользоваться А, проверит, определено ли такое значение, и если да - воспользуется им.
Это, конечно, только предположение.
Просто, может быть, пользователь может подгружать разные версии хедеров. И не хочет разбираться, что данный конкретный хедер объявляет, а что нет. Захочет воспользоваться А, проверит, определено ли такое значение, и если да - воспользуется им.
Это, конечно, только предположение.
как я уже сказал - логичнее было бы делать макрос *_DEFINED, как у FILE, wchar_t и т.п.
о! кажися я понял.
наводит на некоторые подозрения следующая конструкция:
Если эти константы определить через макросы имхо есть вероятность что препроцессор их "вычислит" на этапе препроцессирования. хотя врядли. он же значения их не знает.
в общем, хрен знает.
как нашёл: у меня мой препроцессор запнулся на этом месте
о! кажися я понял.
наводит на некоторые подозрения следующая конструкция:
#define FE_ALL_EXCEPT (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
Если эти константы определить через макросы имхо есть вероятность что препроцессор их "вычислит" на этапе препроцессирования. хотя врядли. он же значения их не знает.
в общем, хрен знает.
как нашёл: у меня мой препроцессор запнулся на этом месте

stdio.h:
/* Standard streams. */
extern FILE *stdin; /* Standard input stream. */
extern FILE *stdout; /* Standard output stream. */
extern FILE *stderr; /* Standard error output stream. */
/* C89/C99 say they're macros. Make them happy. */
#define stdin stdin
#define stdout stdout
#define stderr stderr
возможно. для stdin/stdout/getc и кое-чего ещё я могу это понять.
но для нестандартизованных вещей - нафига?
но для нестандартизованных вещей - нафига?

А что это за стдио.х такой? У меня в MSVC таких строчек нет

Есть идея, что для совместимости.
т.е. раньше было
Сейчас этот же код написали более чисто, через enum, но для совместимости также оставили и define-ы.
т.е. раньше было
#define A 1
#define B 2
#define C 3
#define D 4
Сейчас этот же код написали более чисто, через enum, но для совместимости также оставили и define-ы.
о! это разумно.
2kaifa: я тот код вижу у себя в /usr/include/stdio.h
2kaifa: я тот код вижу у себя в /usr/include/stdio.h
стандартизован в данном случае /usr/include/fenv.h
ок, fenv.h - стандартизован. просто плохой пример.
чего нельзя сказать, например про resource.h
чего нельзя сказать, например про resource.h
Можешь пояснить, в чём заключается совместимость?
Я пока вижу только одно: в #ifdef или #ifndef.
Ну, ещё переопределения через тот же препроцессор.
---
...Я работаю антинаучным аферистом...
Я пока вижу только одно: в #ifdef или #ifndef.
Ну, ещё переопределения через тот же препроцессор.
---
...Я работаю антинаучным аферистом...
> Я пока вижу только одно: в #ifdef или #ifndef.
> Ну, ещё переопределения через
Именно для этого.
Это же библиотечные файлы, поэтому их стараются менять так, чтобы новая версия была максимально совместима с предыдущими.
> Ну, ещё переопределения через
Именно для этого.
Это же библиотечные файлы, поэтому их стараются менять так, чтобы новая версия была максимально совместима с предыдущими.
А где-нибудь это используется?
---
...Я работаю антинаучным аферистом...
---
...Я работаю антинаучным аферистом...
хз
но может быть как раз ifdef используется, что-нибудь типа такого в самой проге:
но может быть как раз ifdef используется, что-нибудь типа такого в самой проге:
#ifndef A
#define A 1
#endif
А зачем такое делать, если в случае ссылки на неопределённое "А,"
транслятор должен выдать сообщение об ошибке?
Или зачем дублирование кода?
---
...Я работаю антинаучным аферистом...
транслятор должен выдать сообщение об ошибке?
Или зачем дублирование кода?
---
...Я работаю антинаучным аферистом...
> А зачем такое делать, если в случае ссылки на неопределённое "А,"
> транслятор должен выдать сообщение об ошибке?
дык, цель написания программы не в том, чтобы компилятор выдал ошибки, если что-то не так, а в том, чтобы программа работала, а перед этим корректно компилировалась.
> Или зачем дублирование кода?
Потому что опять же, например, в самой древней библиотеке этих констант вообще не было, поэтому их приходилось определять в самой проге.
> транслятор должен выдать сообщение об ошибке?
дык, цель написания программы не в том, чтобы компилятор выдал ошибки, если что-то не так, а в том, чтобы программа работала, а перед этим корректно компилировалась.
> Или зачем дублирование кода?
Потому что опять же, например, в самой древней библиотеке этих констант вообще не было, поэтому их приходилось определять в самой проге.
Зачем тогда писать усовершенствованную библиотеку,
если ожидаешь выполнение той же работы на уровне программирования.
В старых программах же не писалось "А?"
Там, скорее всего, писали просто 1.
И уж тем более не "#ifndef".
---
...Я работаю антинаучным аферистом...
если ожидаешь выполнение той же работы на уровне программирования.
В старых программах же не писалось "А?"
Там, скорее всего, писали просто 1.
И уж тем более не "#ifndef".
---
...Я работаю антинаучным аферистом...
1. Библиотеки расчитаны на работу и со старым и с новым кодом.
2. Старый код рассчитывает на то, что в библиотеке будут #define-ы
3. Но новый код удобнее писать без #define-ов, удобнее когда те же константы объявлены, как enum
Соответственно, вывод:
библиотека должна поддерживать и #define-ы, и enum
2. Старый код рассчитывает на то, что в библиотеке будут #define-ы
3. Но новый код удобнее писать без #define-ов, удобнее когда те же константы объявлены, как enum
Соответственно, вывод:
библиотека должна поддерживать и #define-ы, и enum
Как насчёт модульности?
Может, стоило бы разделить библиотеку на три части?
---
...Я работаю антинаучным аферистом...
Может, стоило бы разделить библиотеку на три части?
---
...Я работаю антинаучным аферистом...
> Может, стоило бы разделить библиотеку на три части?
И как бы выглядел процесс подключения этих частей? И что полезного дало бы такое разделение?
И как бы выглядел процесс подключения этих частей? И что полезного дало бы такое разделение?
2. Старый код рассчитывает на то, что в библиотеке будут #define-ыПриведи пример кода, который соберется с константой объявленной через define, но не соберется с константной реализованной через enum. "ifdef A" не использовать.
3. Но новый код удобнее писать без #define-ов, удобнее когда те же константы объявлены, как enum
> "ifdef A" не использовать.
Сначала ты сам вводишь ограничение, а потом просишь его обойти.
ps
Почему ты считаешь, что старый код не использовал #ifdef?
Сначала ты сам вводишь ограничение, а потом просишь его обойти.
ps
Почему ты считаешь, что старый код не использовал #ifdef?
Не следует использовать ifdef для тех констант, которые определяют числовое значение, а не поддержку какой-то фичи.
#include <this-damn-library-X.X.h>
Оно дало бы куда более читаемый код
Со всеми вытекающими.
---
...Я работаю антинаучным аферистом...
Оно дало бы куда более читаемый код
Со всеми вытекающими.
---
...Я работаю антинаучным аферистом...
Такое название напрягло бы пользователей указанной библиотеке.
ps
В рассматриваемой задаче есть три субъекта, у каждого из субъектов свои цели:
1. Автор библиотеки. Цель: упростить пользование данной библиотекой.
2. Автор legacy-кода. Цель: воспользоваться усовершенствованной библиотекой, с как можно меньшим изменением собственного кода
3. Автор нового кода. Писать кода, используя самые удобные и эффективные средства (best practices) на данный момент.
Можно заметить, что оригинальное решение автора библиотеки обеспечивало наилучшее достижение целей всех трех субъектов.
Твое же предложение осложняет жизнь всем трех субъектам, не давая ничего взамен.
Зачем тогда использовать твое решение? Побыть мазохистом?
ps
В рассматриваемой задаче есть три субъекта, у каждого из субъектов свои цели:
1. Автор библиотеки. Цель: упростить пользование данной библиотекой.
2. Автор legacy-кода. Цель: воспользоваться усовершенствованной библиотекой, с как можно меньшим изменением собственного кода
3. Автор нового кода. Писать кода, используя самые удобные и эффективные средства (best practices) на данный момент.
Можно заметить, что оригинальное решение автора библиотеки обеспечивало наилучшее достижение целей всех трех субъектов.
Твое же предложение осложняет жизнь всем трех субъектам, не давая ничего взамен.
Зачем тогда использовать твое решение? Побыть мазохистом?
Нужно учиться не бояться изменять код.
Особенно в тех случаях, когда изменения касаются нескольких
строк.
В конце концов, "природа не храм, а мастерская."
Довольно часто имеет смысл воспользоваться только небольшой
частью библиотеки, и вот тогда начинается весёлая жизнь.
Сможешь объяснить, на кой чёрт нужны исходники, если проще будет
написать всё сызнова, чем выдрать готовое.
---
...Я работаю антинаучным аферистом...
Особенно в тех случаях, когда изменения касаются нескольких
строк.
В конце концов, "природа не храм, а мастерская."
Довольно часто имеет смысл воспользоваться только небольшой
частью библиотеки, и вот тогда начинается весёлая жизнь.
Сможешь объяснить, на кой чёрт нужны исходники, если проще будет
написать всё сызнова, чем выдрать готовое.
---
...Я работаю антинаучным аферистом...
Нужно учиться не бояться изменять код.
Автор стандартных хедеров не имеет право совать свой нос в такие вопросы. Существуют гиганские проекты, программисты которых уже все, например, умерли. И никто не собирается разбираться, на что в них нужно заменить
#ifdef A
...
#endif
И уж тем более отлаживать, если заменил на что-то неподходящее!..
Не следует использовать ifdef для тех констант, которые определяют числовое значение
Почему это?
Есть функция f(int и этот int задает код операции. Возможны операции OPERATION_1, OPERATION_2, ... OPERATION_100. Это define-ы. Я пишу
#ifdef OPERATION_58
//Функция может выполнить операцию 58
f(OPERATION_58);
#else
//Не может (старая версия библиотеки, или еще чего?).
//Достигаем той же функциональности как-то еще
f(OPERATION_24);
f(OPERATION_37);
do_somthing_else;
#endif
PS И еще раз повторю - не автор библиотеки должен решать
следует использовать ifdef для тех констант, которые
или нет...
Оставить комментарий
yolki
Во некоторых .h файлах довольно часто встерчается такое:В чём потусторонний смысл определять такой макрос?