С++ - стильная или эффективная?

Будучи написанием Java-кода на протяжении многих лет, я был поражен, когда увидел этот оператор С++:

int a,b;
int c = (a=1, b=a+2, b*3);

Мой вопрос: это выбор стиля кодирования, или он имеет реальную выгоду? (Я ищу практический пример использования)

Я думаю, что компилятор увидит его так же, как и следующее:

int a=1, b=a+2;
int c = b*3;

(Какое официальное название для этого? Я предполагаю, что это стандартный синтаксис C/С++.)

Ответ 1

Это оператор запятой, используемый дважды. Вы правильно оцениваете результат, и я не вижу смысла использовать его таким образом.

Ответ 2

Похож на неясное использование оператора a (запятая).

Это не репрезентативный способ делать вещи на С++.

Ответ 3

Единственное использование "хорошего стиля" для оператора запятой может быть в операторе for, который имеет несколько переменных цикла, использовал что-то вроде этого:

// Copy from source buffer to destination buffer until we see a zero
for (char *src = source, *dst = dest; *src != 0; ++src, ++dst) {
    *dst = *src;
}

Я помещаю "хороший стиль" в цитаты с испугом, потому что почти всегда есть лучший способ, чем использовать оператор запятой.

Другой контекст, где я видел это, используется с тернарным оператором, когда вы хотите иметь несколько побочных эффектов, например,

bool didStuff = DoWeNeedToDoStuff() ? (Foo(), Bar(), Baz(), true) : false;

Опять же, есть лучшие способы выразить такие вещи. Эти идиомы - прорыв с тех дней, когда мы могли видеть только 24 строки текста на наших мониторах, и сжатие большого количества материала в каждой строке имело практическое значение.

Ответ 4

Не знаю свое имя, но, похоже, отсутствует Руководство по кодированию безопасности работы!

Серьезно: С++ позволяет вам делать много вещей во многих контекстах, даже если они не обязательно звучат. С большой силой приходит большая ответственность...

Ответ 5

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

Хотей

Ответ 6

В вашем примере кода используются два не очень известных новичкам (но не очень скрытые) функции выражений C:

  • оператор запятой: обычный двоичный оператор, роль которого заключается в том, чтобы вернуть последний из двух операндов. Если операнды являются выражением, они оцениваются слева направо.
  • присваивание как оператор, который возвращает значение. Назначение C не является инструкцией, как на других языках, и возвращает значение, которое было назначено.

Большинство случаев использования обеих этих функций связаны с некоторой формой обфускации. Но есть некоторые законные. Дело в том, что вы можете использовать их везде, где вы можете предоставить выражение: внутри if или while условно, в блоке итерации цикла цикла, в параметрах вызова функции (используется кома, вы должны использовать скобки, чтобы избежать путаницы с фактическими параметрами функции), в параметре макроса и т.д.

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

Например, обратная функция может быть записана, как показано ниже, благодаря оператору запятой:

void reverse(int * d, int len){
    int i, j;

    for (i = 0, j = len - 1 ; i < j ; i++, j--){
       SWAP(d[i], d[j]);
    }
}

Другое законное (не запутанное, действительно) использование оператора комы, которое я имею в виду, - это макрос DEBUG, который я нашел в каком-то проекте, определенном как:

#ifdef defined(DEBUGMODE)
#define DEBUG(x) printf x
#else
#define DEBUG(x) x
#endif

Вы используете его как:

DEBUG(("my debug message with some value=%d\n", d));

Если DEBUGMODE включен, вы получите printf, если не будет вызываться функция-обертка, но выражение между скобками все еще действует C. Дело в том, что любой побочный эффект печатного кода будет применяться как в коде деблокирования и код отладки, например, введенный:

DEBUG(("my debug message with some value=%d\n", d++));

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

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

Я согласен, что оператор присваивания является отличным источником ошибок, потому что его можно легко смутить с условным выражением.

Я согласен, что поскольку запятая также используется с другим смыслом в других контекстах (вызовы функций, списки инициализации, списки объявлений), это был не очень хороший выбор для оператора. Но в основном это не хуже, чем использование < и > для параметров шаблона в С++ и существует в C с гораздо более старых дней.

Ответ 7

Его стиль строго кодирования и не будет иметь никакого значения в вашей программе. Тем более, что любой достойный компилятор С++ оптимизирует его для

int a=1; 
int b=3;
int c=9;

Математика даже не будет выполняться во время назначения во время выполнения. (и некоторые из переменных можно даже полностью исключить).

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

Ответ 8

Является ли это выбором стиля кодирования или он имеет реальную выгоду? (Я ищу практический пример использования)

Это и выбор стиля кодирования, и он имеет реальную выгоду.

Это явно другой стиль кодирования по сравнению с вашим эквивалентным примером.

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

Случай использования: Боб приходит ко мне с куском кода, содержащего эту строку. Я передал его в маркетинг.

Ответ 9

Вы обнаружили отвратительное злоупотребление оператором запятой, написанным программистом, который, вероятно, хочет, чтобы у С++ было несколько назначений. Это не так. Мне напомнили, что старый увидел, что вы можете писать FORTRAN на любом языке. Очевидно, вы можете попробовать написать Dijkstra язык охраняемых команд в С++.

Чтобы ответить на ваш вопрос, это чисто вопрос (плохой) стиль, и компилятор не заботится о том, чтобы компилятор генерировал точно такой же код, как и от того, что программист на С++ считал бы разумным и разумным.

Это можно сделать сами, если вы создадите две маленькие примерные функции и скомпилируете оба параметра -S.