Логическое значение назначения в C - PullRequest
1 голос
/ 02 декабря 2009
while (curr_data[1] != (unsigned int)NULL &&
    ((curr_ptr = (void*)curr_data[1]) || 1))

Вопрос из двух частей.

Что будет (curr_ptr = (void*)curr_data[1]) оценивать логически. TRUE

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

Ответы [ 4 ]

3 голосов
/ 02 декабря 2009

(curr_ptr = (void*)curr_data[1]) будет иметь значение ИСТИНА, если это не нулевой указатель.

Предполагая, что curr_data является массивом указателей, и вам нужно запустить цикл, пока второй из этих указателей не равен нулю, а при присвоении его значения curr_ptr я бы сделал:

while ((curr_ptr = (void*)curr_data[1]) != NULL) { ... }
2 голосов
/ 02 декабря 2009

Чтобы ответить на ваши вопросы:

  1. Будет установлено значение true, если curr_ptr не установлено на NULL (т.е. curr_data[1] не равно 0).
  2. Я считаю, что это законно, но есть большие проблемы с этой строкой кода.

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

  1. (unsigned int)NULL смешно. Зачем ты это делаешь? Вероятно, это будет то же самое, что просто написать 0 (не уверен, гарантируется ли это стандартом).
  2. Какие данные содержатся в curr_data[1], если они приводятся к указателю (и указатели приводятся к нему)? Если предполагается, что указатель содержит целочисленный тип, вы должны использовать для этой цели тип intptr_t или uintptr_t, предоставленный в <stdint.h> (если ваш компилятор не поддерживает C99 *, может быть приемлемый заменитель).
  3. || 1 в конце кажется избыточным. Если бы curr_ptr = (void*)curr_data[1] оценил бы как ложное, мы бы поймали это в первом условии.

Это может быть боль в заднице, но серьезно пересмотреть эту строку. Похоже на запись в IOCCC.

1 голос
/ 02 декабря 2009

Назначения - это выражения на C, так что то, что у вас есть, работает. Изменение ; на {} означает то же самое и гораздо понятнее, сделайте это как минимум. Следует избегать присвоений в условиях, когда у вас есть более четкая альтернатива (что обычно является верным), но если она наиболее ясна в этом месте, используйте ее.

Результатом присваивания является присвоенный объект. a = value выполнит задание и затем оценит до a. Это используется для таких вещей, как a = b = 0.

Для дальнейшей очистки кода нет необходимости в приведении типа void, и если это символы, используйте '\ 0' (нулевой символ) вместо NULL (который предполагается использовать только с указателями).

0 голосов
/ 02 декабря 2009

Вам не придется проходить через "большие искажения", которые полностью эквивалентны

while (curr_data[1]) {
    curr_ptr = (void *)curr_data[1];
...