nataraj: (Default)
[personal profile] nataraj
[personal profile] vitus_wagner, [personal profile] beldmit, ну и кто еще в теме разбирается...

Расскажите, насколько легальна в Си вот такая штука:

Есть некий массив сопоставляющий имя и значение, и есть еще возможность значения по умолчанию, которое имени не имеет.

Чувак предлагает делать так:

#define NAME_DEFAULT ((const char *) -1)        /* pseudo-name for default value */


А потом проверять

if(Chto_to->name == NAME_DEFAULT)


Где name -- это char*

Для меня это какое-то страшное сишное конлдунство, я не могу оценить насколько оно корректно и переносимо между компиляторами.

Потому как я бы право слово скорее #define NAME_DEFAULT "" сделал бы. Ибо пустого имени все равно не бывает. И потом при помощи сравнения строк его проверял бы. Но может это у меня просто нету правильной сишной закалки.

Date: 2018-03-04 07:04 pm (UTC)
beldmit: (Программизм)
From: [personal profile] beldmit
Тут предлагается сравнивать указатели, а не значения по ним. А дальше вопрос, как оно инициализируется.

Если пустого имени не бывает, то я бы для значения использовал NULL.

Date: 2018-03-04 07:45 pm (UTC)
vitus_wagner: My photo 2005 (Default)
From: [personal profile] vitus_wagner
Ну в общем правильно не нравится. Понятно, что сравнение с пустой строкой более ресурсоемко, даже если не использовать строковое сравнение, а проверять на то что по указателю char * находится нулевой символ - налетаем на +1 разыменование указателя при каждом сравнении.

Но я бы не стал на этом месте экономить. Потому что никто не обещал что этот хитрый трюк который сейчас позволяет сэкономить целое разыменование, завтра, версий этак через 10 компилятора, не превратится в уязвимость.

Помнится в catdoc мне через 20 лет после написания много какие подобные трюки пришлось править.

Date: 2018-03-04 07:59 pm (UTC)
beldmit: (Программизм)
From: [personal profile] beldmit
Массив.

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

Date: 2018-03-04 08:03 pm (UTC)
norian: (Default)
From: [personal profile] norian
если хто-нть полезет смотреть строку без проверки, поимеет сегфолт, причём случайным образом в рантайме

поэтому лучше пустая строка, или не пустая, какая-нть "MY_DEFAULT_NAME"

Edited Date: 2018-03-04 08:08 pm (UTC)

Date: 2018-03-04 08:35 pm (UTC)
qkowlew: На Зилантконе меня сфоткали мыльницей. Мыльницам не позирую! (Default)
From: [personal profile] qkowlew
IMHO:

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

Что будет где-то приводить к нормальному сравнению, где-то - к неверному при неких входных данных (что особенно неприятно), где-то и к сегфолту (впрочем, вот щас так не могу придумать точно где, хехе).
Edited Date: 2018-03-04 08:38 pm (UTC)

Date: 2018-03-04 08:48 pm (UTC)
qkowlew: На Зилантконе меня сфоткали мыльницей. Мыльницам не позирую! (Default)
From: [personal profile] qkowlew
Так. Давай обратимся к смысловой части.

Если имя в массиве найдено - возвращаем соотв ему значение (char * на строку)
Если имя в массиве не найдено - возвращаем NULL

Если значение в массиве найдено - возвращаем соотв ему имя (char * на строку)
Если значение в массиве не найдено - возвращаем NULL

Когда и где нужен пресловутый "default name"?
Edited Date: 2018-03-04 08:50 pm (UTC)

Date: 2018-03-04 08:59 pm (UTC)
beldmit: (Default)
From: [personal profile] beldmit
Я теоретически могу себе представить такое. Сохранение конфига, где важно отличить не установленное значение от установленного по умолчанию. Но на мой вкус это экзотика.

Date: 2018-03-04 11:12 pm (UTC)
qkowlew: На Зилантконе меня сфоткали мыльницей. Мыльницам не позирую! (Default)
From: [personal profile] qkowlew
Э нет.

"элементы конфига" - это одна сущность.
"массив" - это другая сущность.

Соблазн в plain C одну сущность строго описать другой, велик, но мне кажется неразумным.

Date: 2018-03-04 11:09 pm (UTC)
qkowlew: На Зилантконе меня сфоткали мыльницей. Мыльницам не позирую! (Default)
From: [personal profile] qkowlew
У компиляторов Си есть ОДНО ясно видимое, всегда трактуемое одинаково "особое значение указателя" - NULL.

С моей точки зрения, тем не менее, использовать "особое значение" в подобном сравнении можно, и это будет "менее взрывчато". Но только одним способом.

Не преобразуя целую константу в char *, а используя для ОБОИХ сравниваемых элементов union с целочисленным значением соответствующей длины. То есть что-то типа:

#if sizeof(char *) == 2
#define DEFAULT1 (int)-1
#define DEFAULT2 (int)-2
union { int itemintvalue, char *item }

#elif sizeof(char *) == 4
#define DEFAULT1 (long int)-1
#define DEFAULT2 (long int)-2

union { long int itemintvalue, char *item }
...

#endif


...

if (itemintvalue == NULL) { } /* тут можно и item */
if (itemintvalue == DEFAULT1) { }
if (itemintvalue == DEFAULT2) { }

В этом случае "компиляторозависимые" фишки окажутся строго в "правильном месте", их будет легче править, а в основном потоке операций не будет лишних ворнингов и рантайм ерроров...

Пока не случится так, что строка массива "ляжет" на адрес, который окажется DEFAULT1 или DEFAULT2 ;)

Но в нынешнем мире я бы не стал так делать. :)
Edited Date: 2018-03-04 11:14 pm (UTC)

Date: 2018-03-04 09:55 pm (UTC)
slobin: (Default)
From: [personal profile] slobin
Отвечая на заданный вопрос: нет, нельзя, взорваться может в любой момент при смене версии компилятора. Нынешние компиляторы обожают взрыватся при неопределённом поведении.

Отвечая на все незаданные вопросы сразу (включая и пустую строку тоже, она НЕ исключение): помнишь народную мудрость про зарплатную ведомость и сотрудника с фамилией Итого? Если в одном словаре могут оказаться и данные от пользователей (имена ключей) и данные от программиста (MY_DEFAULT_KEY, пустая строка), то помечаться как специальные должны первые, а не вторые. В одном проекте, в котором я принимал участие, к именам ключей от пользователей приклеивалась тильда: "~Иванов", "~Петров", "Итого", но ни в коем случае не "Иванов", "Петров", "~Итого" -- при втором подходе рано или поздно кто-то впишет эту тильду к себе в паспорт. Но такой подход тормозит, да. Если важно, чтобы ещё и не тормозило -- ну, тогда думать надо. :-)

Можно иметь несколько разных ссылок на разные пустые (или даже не пустые) строки для разных целей, но тогда нужно очень внимательно смотреть, когда ты сравниваешь ссылки, а когда значения. Рано или поздно кто-нибудь ошибётся. :-( Но зато быстро.

... И мировой получает 2400, и председатель 2400 ...

Date: 2018-03-05 07:28 am (UTC)
beldmit: (Default)
From: [personal profile] beldmit
"Третий был без имени, но со стажем в полторы тыщи лет"...

Date: 2018-03-07 12:44 am (UTC)
rish: (Default)
From: [personal profile] rish
=)))))

Profile

nataraj: (Default)
Swami Dhyan Nataraj

July 2024

S M T W T F S
 123456
789 10111213
14151617181920
21222324252627
28293031   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 23rd, 2026 11:50 am
Powered by Dreamwidth Studios