LINUX.ORG.RU

Валидное ли это c-выражение?

 ,


0

4

subj:

void foo(char *a, char b, char c) {
	(a ? *a : b) = c;
}

GCC съедает без проблем, SDCC ругается что слева не lvalue.

upd. Под плюсами корректное, под си нет.

upd#2, solution.

★★★★★

Последнее исправление: thunar (всего исправлений: 5)
Ответ на: комментарий от MKuznetsov

Косвенно оно возвращает c в *a если там не нулевой указатель.
Сделано это чтобы можно было инициализировать

int &r = cond ? a : b;
в c++, в c соответсвенно такой необходимости нет и выражение невалидно

mittorn ★★★★★
()
Последнее исправление: mittorn (всего исправлений: 1)

Этот фокус нужно делать так:

#include <iostream>

int main()
{
    int* a = new int;
    *a = 4;
    
    // int* a = nullptr;

    int b = 5;

    *(a ? a : &b) = 10;

    if (a)
        std::cout << "a=" << *a << std::endl; 
        
    std::cout << "b=" << b << std::endl;
}
rumgot ★★★★★
()

(a ? *a : b) = c;

А в чем смысл этого выражения? Ну то есть если a=NULL, то измениться должна локальная копия b?

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

Тут важен сам механизм присваиваивания. Для C оно будет выглядеть так же. И для char тоже. Ты по сути скажи что-то лучше. А то нашёл тоже, к чему докопаться, смехота.

rumgot ★★★★★
()

не надо так писать, даже если это валидное выражение.

#define SET_A(a, b, c) ((__builtin_types_compatible_p(typeof(a), char*) && (a)) ? (*(char*)(a) = c) : (b = c))

не претендую ни на что, но все-таки понятнее вашего и ф-цию не надо новую писать, и b все-таки не в пустую присваивается значение, но это gnu99, не C99.

А в C11 уже добавили полноценную стандартную проверку типов.

IvanRia
()
Последнее исправление: IvanRia (всего исправлений: 2)
Ответ на: комментарий от IvanRia

но вообще, такую вещь удобнее и логичнее оформить как ф-цию, тогда проверки пройдут автоматически, но тогда мы вернемся к первому моему утверждению - «не стоит так писать»

IvanRia
()
  • Markdown
Пустая строка (два раза Enter) начинает новый абзац. Знак '>' в начале абзаца выделяет абзац курсивом цитирования.
Внимание: прочитайте описание разметки Markdown.
Используйте Ctrl-Enter для размещения комментария