LINUX.ORG.RU
Ответ на: комментарий от Kroz

Но вот со словом «убережёт» я всё еще не согласен.

ОК. Даст предсказуемый воспроизводимый результат. Сишные (и C++’ные) программы меня расстраивают не тем, что иногда глючат (программу с ошибками можно написать на любом языке), а тем, что глюки могут быть абсолютно разными в зависимости от опций оптимизации и разрядности платформы.

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

А он и не обязан быть, он все типы int**_t по стандарту опциональны и имеют право отсутствовать. Обязаны быть только int_fast**_t и int_least**_t, и в истинно кроссплатформенном коде только их и можно использовать

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

В первом слове 9 букв, во втором - 4. Ты, это, аккуратнее - не перетрудись. Если много раз слово из 8 букв напишешь - пиши сразу и заявление работодателю о премировании за столь серьезный труд.

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

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

Все вызовы функций в Си - это бинарные протоколы.

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

где-то может быть бесконечным циклом.

Да, например, на всё ещё актуальных DSP TI TMS320C55x, где char, short и int - 16 бит, long - 32 бит, а long long - целые 40 бит.

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

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

ну нет же

и разрядности платформы

тоже нет

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

который на некоторых платформах может быть отличным от широко используемого

если вы будете писать под такие платформы, вы об этом узнаете

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

а можно юз-кейс, когда вам нужен будет мультиплатформенный код между архитектурами с разной разрядностью int? и при этом, чтобы ещё и равная разрядность у интов была важна?

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

ну нет же

Я же конкретный пример привёл:

char a[100000];
for (int i = 0; i < 100000; i++) a[i] = 0;

Там, где int > 16 бит, будет работать. Иначе в зависимости от опций оптимизатора, так как UB.

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

когда вам нужен будет мультиплатформенный код между архитектурами с разной разрядностью int?

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

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

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

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

-Wall -Wextra -Wconversion (ток для шланг) -Werror спасут отца русского говнокодинга

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

Во-первых, чтобы не рехнутся

Во-вторых, тогда уж сразу в машинных кодах

В-третьих, у арм32, арм64, мипс, интел, амд64 одинаковая разрядность int. Вопрос, для каких ещё архитектур вы писали код на С и что там с переносимостью его на типичное железо?

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

варнинг будет в таком коде в худшем случае - это первое, у вас тут магические числа вместо констант - это второе

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

Это ты с бинарными протоколами передачи данных не сталкивался… Да и на микроконтроллерах как-то приятней, чтобы тип был той самой разрядности, что тебе нужно! А не приколы вроде 16-битного int'а на некоторых 8-битных микроконтроллерах.

OnlyAsk
()
Ответ на: комментарий от next_time

варнинг будет в таком коде в худшем случае - это первое

$ cat test.c
#define N 100000

int main()
{
        char a[N];
        for (int i = 0; i < N; i++) a[i] = 0;
        return a[0];
}
$ gcc -Wall -Wextra test.c
$ 

Никаких варнингов.

у вас тут магические числа вместо констант - это второе

В

#define N 100000

... // много строк

char a[N];
for (int i = 0; i < N; i++) a[i] = 0;

будет ещё сложнее заметить ошибку.

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

Во-первых, чтобы не рехнутся

include 'macros.inc'
include 'debug.inc'
MEOS_APP_START
CODE
   print 'Hello world!'
   mcall -1
DATA
UDATA
MEOS_APP_END

читается не сложнее, чем

#include <stdio.h>
int main()
{
  printf("Hello world!");
  return 0;
}

Во-вторых, тогда уж сразу в машинных кодах

Смысл? У ассемблера есть преимущество перед Си (есть код на ассемблере, непредставимый на Си). У машкодов перед ассемблером нет.

В-третьих, у арм32, арм64, мипс, интел, амд64 одинаковая разрядность int. Вопрос, для каких ещё архитектур вы писали код на С и что там с переносимостью его на типичное железо?

И что? Кстати, у интел не везде. Скомпилируй программу при помощи Borland C++ 3.1. А переносимость решается лапшой из ifdef’ов и autotools’ами.

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

А теперь давай такое!

struct dog {
  char name[666];
  double weight;
};

struct shaurmecnya {
  struct dog foods[1337];
};

void fnc(int i, int j) {
  struct shaurmecnya s[2];
  strcpy(s[i].foods[666].name, "BadBoy");
  s[i].foods[j].weight = 12.0/46.5;
}

insw
()
Ответ на: комментарий от insw
struc food
  name resd 666
  weight resq
endstruc

struc shaurmecnya
  dog resb food_size*1337
endstruc

badboy db "BadBoy"
c12    dq 12.0
c465   dq 46.5
res    resq

proc    fnc 
%$i     arg 
%$j     arg 
        mov     eax,[ebp + %$i] 
        mov     ebx,[ebp + %$j]
        sub     esp,shaurmechnya_size*2
        mov     ecx,[esp + eax*shaurmechnya_size+666*food_size+dog.name]
        push    badboy
        push    ecx
        call    strcpy
        finit
        fld     c12
        fdiv    c465
        fst     res
        mov     [esp + eax*shaurmechnya_size+ebx*food_size+dog.weight],res
endproc
monk ★★★★★
()
Ответ на: комментарий от OnlyAsk

Это ты с бинарными протоколами передачи данных не сталкивался

Сталкивался. Я просто возразил против ультимативного «типы с фиксированой длиной нужны, а int не нужен».

Dudraug ★★★★★
()

Тебе религия запрещает заслать в комитет пропозал?

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

можно так:



void test ( void )
{
   struct platform_limitations { int int_at_least_16_bit : (~0u>>8)>>8 >= 0xffffu ; };

   char a[100000];
   for (int i = 0; i < 100000; i++) a[i] = 0;
}

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

вызов функции читается не сложнее, чем

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

У ассемблера есть преимущество перед Си (есть код на ассемблере, непредставимый на Си). У машкодов перед ассемблером нет.

есть код, представимый в машкодах, но не в ассемблере (GPU)

Скомпилируй программу при помощи Borland C++ 3.1

не смогу найти настолько древний компилятор

А переносимость решается лапшой из ifdef’ов и autotools’ами

нет, в вышеупомянутых случаях не решается. вы на вопрос-то ответьте.

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

нет, в вышеупомянутых случаях не решается. вы на вопрос-то ответьте.

Отвечаю: переносимый код я писал только на переносимых языках. Таких как паскаль, лисп, джаваскрипт.

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

есть код, представимый в машкодах, но не в ассемблере (GPU)

Любые машкоды представимы в ассемблере. Или ты про отсутствие транслятора SASS->машкоды? Так есть PTX.

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

Сишные (и C++’ные) программы меня расстраивают не тем, что иногда глючат (программу с ошибками можно написать на любом языке), а тем, что глюки могут быть абсолютно разными в зависимости от опций оптимизации и разрядности платформы.

Кстати, в С++ хорошо с этим, главное тесты запускать с включенной оптимизацией, и на всех нужных платформах.

В каких-нибудь явах, да си шарпах вообще баги не найти, так как jit, то есть баг может появиться лишь после прогрева на определенных данных от внезапной новой оптимизации, которой на тестах не будет никогда…

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

Кстати, в С++ хорошо с этим, главное тесты запускать с включенной оптимизацией, и на всех нужных платформах.

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

// "ABC" in arrStr ? 
bool Find(const ArrayOfStrings &arrStr)
{
  ArrayOfStrings::const_iterator it;
  for (it = arrStr.begin(); it != arrStr.end(); ++it)
  {
    unsigned n = it->find("ABC");
    if (n != string::npos)
      return true;
  }
  return false;
};

В каких-нибудь явах, да си шарпах вообще баги не найти, так как jit, то есть баг может появиться лишь после прогрева на определенных данных от внезапной новой оптимизации, которой на тестах не будет никогда…

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

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

Любые машкоды представимы в ассемблере.

вообще-то, нет, тем более, что ассемблер - семейство языков, не 1

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

вопрос был не про то, писали ли вы переносимый код (кстати, джаваскрипт непереносим на аппаратные архитектуры с машинным словом меньшим 32 бита), вопрос про то, переносили ли вы его? запускали на архитектурах, на которых sizeof(int) != 4 или нет?

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

В Си возможны баги от оптимизации, потому что в стандарте есть UB

не путайте кислое со сладким - баги от UB - это баги от UB, а не от оптимизации

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

запускали на архитектурах, на которых sizeof(int) != 4 или нет?

Разумеется. На архитектуре 8086. Паскаль работает. Си приходилось кусочно переписывать.

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

не путайте кислое со сладким - баги от UB - это баги от UB, а не от оптимизации

Это понятно. Но проявляются они при оптимизации. Программа может быть протестирована на всех архитектурах и доступных компиляторах и внезапно перестать работать на новом компиляторе. При том, что новый компилятор полностью соответствует стандарту, просто у него лучше оптимизатор. А гарантировать отсутствие UB никто не может (судя по количеству исправлений в программах, написанных профессиональными высокооплачиваемыми программистами). Например, в PhysX UB существовал как минимум 2 года.

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

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

вообще-то, нет, тем более, что ассемблер - семейство языков, не 1

Ассемблер — мнемокод для машинного кода конкретного процессора. Именно поэтому для любого процессора ассемблер существует.

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