LINUX.ORG.RU
ГолосованияГолосования (не подтверждено)

Какой кусок исходного кода на Си Вам кажется более красивым (см. подробности)

 , ,


0

2

первый вариант:

a[0] = get_data(0);
a[1] = get_data(1);
a[2] = get_data(2);
a[3] = get_data_3();
a[4] = get_data(4);
a[5] = get_data_5();

второй вариант:

for(int i = 0; i < sizeof(a)/sizeof(a[0]); i++) {
  switch(i) {
    case 3: a[i] = get_data_3(); break;
    case 5: a[i] = get_data_5(); break;
    default: a[i] = get_data(i); 
  }
}
★★★★★

Последнее исправление: Virtuos86 (всего исправлений: 2)

Ответ на: комментарий от Deleted

А ведь все равно, для машины ничего не поменялось :) Просто ваши ники можно переставить местами в моем посте...

Я не понял одного, о чем речь, о гламурности или об эффективности выполнения на ЦП? Если о гламурности, то говно и то и то.

for(int i = 0; i < sizeof(a)/sizeof(a[0]); i++) {
  switch(i) {
    case TYPE_1:
                  a[i] = get_data_name1();
                  break;
    case TYPE_2:
                  a[i] = get_data_name2();
                  break;
    default:
                 a[i] = get_data(i); 
                 break;
  }
}

И в default ставте break. А то потом влепите после него что-то.

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

За второй кусок кода, у нас бы дропнули с проекта. Да и за первый тоже.

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

я не очень высоко ценю.

Штука в том, что опрос и был нужен для того, чтобы узнать мнение всего сообщества, а не лично Вас. Люди приходили и голосовали, а именно Вы пришли и снесли мало того, что голоса почти 180 человек на тот момент, так ещё и обесценили почти день продумывания пунктов на голосование в котором плотно участвовали несколько человек.

Если лично для Вас это нормально и никто против не возразит (спасибо @Satori кстати), то у меня например желание участвовать в таком сообществе как-то пропадает.

P.S. а сравнить два куска кода на C это крайне важно конечно.

dsl
()
Ответ на: комментарий от Barracuda72

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

Если то, что компилятор не обязан бить тебя по рукам, для тебя значит что можно пихать их сколько угодно каких угодно, то тогда с таким «может» трудно спорить. Только толку в таком «может», которое потенциально приводит к UB.

При этом контроль корректности списка параметров лежит полностью на программисте

Ты писал:

Если там get_data_3(), …, то при stdcall стек может и не попортиться.

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

Фактически же вызывать функцию с параметрами, несовместимыми с тем, как определена функция — UB.

Функция может быть вообще никак не определена.

В этом случае поведение тоже не определено.

utf8nowhere ★★★
()
Ответ на: комментарий от Barracuda72

Это может быть, например, ассемблерная процедура, принимающая первым параметром количество аргументов, каждым четным - тип аргумента, каждым нечетным - его значение. (Да, в современном C есть правильный механизм для этого, но в принципе такую конструкцию представить себе вполне реально).

Раз уж ты такой любитель представлять себе гипотетические реализации, можно представить себе такую конструкцию: имена функций содержат в себе информацию о типах параметров (как в типичных существующих реализациях C++), а в месте вызова, если функция объявлена без прототипа, манглинг производится на основе типов аргуменов (после default argument promotions). Тогда, если типы аргументов не совместимы с типом параметров, компиляция обломится, т.к. не будет найдена соответствующая вызываемой функция. Тогда твои рассуждения:

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

не верны.

Заметь, тебя никто не тянул за язык пускаться в фантазии о каких-то гипотетических реализациях. ;)

utf8nowhere ★★★
()
Ответ на: комментарий от utf8nowhere

Раз уж ты такой любитель представлять себе гипотетические реализации, можно представить себе такую конструкцию: имена функций содержат в себе информацию о типах параметров (как в типичных существующих реализациях C++), а в месте вызова, если функция объявлена без прототипа, манглинг производится на основе типов аргуменов (после default argument promotions). Тогда, если типы аргументов не совместимы с типом параметров, компиляция обломится, т.к. не будет найдена соответствующая вызываемой функция.

P.S. Кстати да, существует реализация почти такая, как я описал.

utf8nowhere ★★★
()
Ответ на: комментарий от dimuska139

Зато будет единый метод get_data со switch внутри (get_data_3 и get_data_5 надо убрать, заменив все методом единым get_data).

get_data, get_data_3 и get_data_5 – некие функции из внешних библиотек. Можно вокруг них накрутить my_get_data, но тогда при чтении кода придётся переходить к телу этого my_get_data, чтобы увидеть что именно он делает.

monk ★★★★★
() автор топика
Ответ на: комментарий от LinuxDebian

Я не понял одного, о чем речь, о гламурности или об эффективности выполнения на ЦП?

Что предпочёл бы увидеть в исходнике модуля, который надо срочно модифицировать для своих нужд.

monk ★★★★★
() автор топика

ИМХО

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

SkyMaverick ★★★★★
()
whatever get_data_done_right(size_t index)
{
  if(index == 3) return get_data_3();
  if(index == 5) return get_data_5();
  return get_data(index);
}

for(...)
{
  a[i] = get_data_done_right(i);
}

Вот этот.

maverik ★★
()
Ответ на: комментарий от Satori

Вайна апросав! Жтригода ждал! Драка среди корректоров! Расскол модераторов, форк лора! Автоматическая регистрация анонимов! Флуд макскома в толксах! Открытие клуба! коментарии из vk! Имиджборда в development! Новости Галерея Форум Трекер Уведомления Поиск Игры Mail.ru крути кейсы скго с бонусами! Профиль фотостраны в профиле лора!

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от monk

Так это ж как раз нормально. Абстракции и все такое. Единый интерфейс get_data_wrapper (например), а «под капотом» разные реализации (вызовы get_data, get_data_3 и get_data_5).

И при написании unit-тестов для функции, использующей get_data_wrapper, делать мок нужно будет лишь для вызова get_data_wrapper - и все, а не для get_data, get_data_3 и get_data_5.

тогда при чтении кода придётся переходить к телу этого my_get_data

А если не использовать функции вообще, то при чтении кода не придется переходить вообще никуда. Но, если серьезно, то в любой IDE можно зажать Ctrl и клацнуть на вызов функции - и тебя сразу перекинет к телу этой функции. Не сказал бы, что это прямо напрягает сильно.

dimuska139 ★★
()
Ответ на: комментарий от utf8nowhere

Если то, что компилятор не обязан бить тебя по рукам, для тебя значит что можно пихать их сколько угодно каких угодно, то тогда с таким «может» трудно спорить. Только толку в таком «может», которое потенциально приводит к UB.

Как же ты спишь-то по ночам с такой мнительностью? Контроль того, будет UB или нет, лежит на программисте, целиком и полностью. Само по себе это UB не является; UB возникает, если программист забыл / запутался и не проконтролировал то, что передает функции. Ситуация ничем не отличается от того, как когда подпрограмма написана на ассемблере, ее объявление на языке C существует отдельно, а их соответствие контролируется программистом. Точно такое же потенциальное UB в случае рассогласования.

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

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

В этом случае поведение тоже не определено.

Лол. Предлагаю тогда прямо сейчас выдернуть из компа шнур питания и выкинуть его в окно, ибо все ассемблерные процедуры не имеют определений на языке C и по такой логике поведение системы в принципе не определено, он в любой момент может взорваться или отправить исследовательскую миссию на Марс. Если же к столь радикальным мерам прибегать не хочется - советую вспомнить, что такое определение функции (definition) и чем оно отличается от объявления (declaration). И да, в силе мое замечание выше - соответствие между объявлениями на C и реализациями на ассемблере полностью на совести программиста, что по твоей логике не исключает UB.

Barracuda72 ★★
()
Ответ на: комментарий от utf8nowhere

имена функций содержат в себе информацию о типах параметров (как в типичных существующих реализациях C++), а в месте вызова, если функция объявлена без прототипа, манглинг производится на основе типов аргуменов (после default argument promotions). Тогда, если типы аргументов не совместимы с типом параметров, компиляция обломится, т.к. не будет найдена соответствующая вызываемой функция

Если функция объявлена без параметров, то не с чем выполнять сравнение на совместимость (прототип-то не известен), и фейл произойдет не на этапе компиляции, а при компоновке (либо при объединении объектных файлов, либо при запуске программы и подгрузке динамической библиотеки - не самая редкая ситуация с теми же плюсами, кстати). Кроме того, вывод на основе типов параметров, вообще говоря, неоднозначен, ибо совершенно неочевидно, до какой степени эти самые promotions должны выполняться, если нам заранее неизвестны сигнатуры функций-кандидатов (как в C++). Поэтому в такой схеме логично в принципе считать объявление функции без параметров либо ошибкой, либо собственно указанием на то, что функция не имеет параметров, как это и сделано в C++ (ЕМНИП, стандарт плюсов, в отличие от C, я наизусть не помню). Так что мои рассуждения в такой ситуации просто не могут иметь места, ибо нет исходной посылки. А там, где могут - в том числе, в современном C - они вполне себе верны)

Заметь, тебя никто не тянул за язык пускаться в фантазии о каких-то гипотетических реализациях. ;)

То, что ты никогда с какими-то вещами не сталкивался, не делает их гипотетическими. Добро пожаловать в реальный мир, где программисты и не такие финты выкручивают порой)

Barracuda72 ★★
()
Ответ на: комментарий от Satori

Кто тебя, олух, в корректоры принял? Только что после тебя чистил ОП про релиз GHC. Потрудись хотя бы ознакомиться с правилами оформления списков [list] на будущее. Не всегда твой зад будут прикрывать более квалифицированные люди.

Virtuos86 ★★★★★
()
Последнее исправление: Virtuos86 (всего исправлений: 1)
Ответ на: комментарий от dimuska139

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

int main()
{
    init_globals();
    read_from_user();
    do_task();
    out_result();
}

и каждая из этих четырёх функций выглядит также.

С тех пор что-то поменялось по принципам выделения куска кода в функцию?

monk ★★★★★
() автор топика
Ответ на: комментарий от dimuska139

И при написании unit-тестов для функции, использующей get_data_wrapper, делать мок нужно будет лишь для вызова get_data_wrapper

И при этом все шансы, что в тестах варианты 3 и 5 будут пропущены. Ведь в интерфейсе get_data_wrapper они ничем не выделяются.

monk ★★★★★
() автор топика
Ответ на: комментарий от monk

будет вызываться как минимум из двух мест

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

Если ты методы получения данных вынесешь в библиотеку (например), то юзеры предпочтут вызывать get_data, не думая, что там под капотом, нежели где-то вызывать get_data, где-то get_data_N и т.п. Можешь не соглашаться, но, на мой взгляд, такая обертка упрощает код визуально и позволяет удобно покрыть код тестами.

варианты 3 и 5 будут пропущены

Нет, потому что get_data_wrapper, конечно, тоже должна быть покрыта своим(-и) отдельным(-и) тестом (тестами). В которых и проверяется то, какие get_data или get_data_N вызываются в каких условиях.

dimuska139 ★★
()
Последнее исправление: dimuska139 (всего исправлений: 3)
Ответ на: комментарий от Barracuda72

Если функция объявлена без параметров, то не с чем выполнять сравнение на совместимость (прототип-то не известен), и фейл произойдет не на этапе компиляции, а при компоновке

И что же, ты считаешь, что такая реализация соответствует стандарту?

Кроме того, вывод на основе типов параметров, вообще говоря, неоднозначен, ибо совершенно неочевидно, до какой степени эти самые promotions должны выполняться, если нам заранее неизвестны сигнатуры функций-кандидатов

Не совсем понимаю, о какой неоднозначности ты говоришь. Default argument promotions в отсутствие прототипа определены стандартом однозначно.

utf8nowhere ★★★
()
Ответ на: комментарий от Barracuda72

Само по себе это UB не является

Что «это»?

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

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

советую вспомнить, что такое определение функции (definition)

Не знаю, почему ты это советуешь мне. Это тебе нужно перечитать 6.9.1 Function definitions и найти там что-нибудь про ассемблер.

utf8nowhere ★★★
()
Ответ на: комментарий от Virtuos86

Кукарекай что хочешь, боец интернетный.

Satori ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.