LINUX.ORG.RU

Fil-c: Rust killer

 , , ,


1

3

https://fil-c.org/

Видево: https://www.youtube.com/watch?v=6Maoe-GMynM

Ъ:

Fil-C — a memory safe implementation of the C and C++ programming languages you already know and love.

Key Features:

Memory Safety: Advanced runtime checks to prevent exploitable memory safety errors. Unlike other approaches to increasing the safety of C, Fil-C achieves complete memory safety with zero escape hatches.

C and C++ Compatibility: Your C or C++ software most likely compiles and runs in Fil-C with zero changes. Many open source programs, including CPython, OpenSSH, GNU Emacs, and Wayland work great in Fil-C. Even advanced features like threads, atomics, exceptions, signal handling, longjmp/setjmp, and shared memory (mmap style or Sys-V style) work. It’s possible to run a totally memory safe Linux userland, including GUI, with Fil-C.

Modern Tooling: Compiler is based on a recent version of clang (20.1.8), supports all clang extensions, most GCC extensions, and works with existing C/C++ build systems (make, autotools, cmake, meson, etc).

Принёс на ЛОР.

Нужна ли борьба с borrow checker? Или продолжаем страдать от ЦеПеПе?

Известны ли уже CVS с ошибками в unsafe блоках?

★★★★

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

Конвейер сломан, векторизация сломана, и это только на поверхности

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

Про реал тайм даже комментировать не буду, по вашему С используется только для обучения студентов?

Нет, я работаю в сфере HFT и по работе пишу «реал тайм» софт, хотя и soft real-time.

Я говорю, что оно не предназначено для real-time систем. Так же, как и Python. Но, несмотря на это, Python очень популярен.

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

Ты свой софт стандартом компилируешь?

Я пишу софт, который компилируется кем угодно компилятором по своему выбору. Предлагаешь писать не на Си, а на языке «gcc-11 c -O1»? Бывает, некоторый софт на таких языках и пишется. Но это попросту означает, что он нафарширован UB, и никто не знает, что с этим делать.

у gcc UB зависит от опций компиляции

UB - свойство программы, не зависящее от компилятора. По стандарту переполнение знакового UB. Нет в стандарте никакого «переполнения в gcc с такими-то опциями», только просто переполнение. Приводит это к эффектам или нет, это уже другой вопрос. В корректно написанной программе нельзя опираться на UB.

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

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

А почему разработчик маленького кусочка программы берет на себя ответственность за завершение всей программы?

Т.е. кто-то думая, что вызвать unwrap – это нормально, делает такой вызов. А потом треть Интернета кукует пока Cloudflare починит сбой.

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

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

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

Я пишу софт, который компилируется кем угодно компилятором по своему выбору

Прямо таки каким угодно? Даже компилятором фортрана? А компилятором Си из unix v4? Сейчас начнутся отмазы что это типа неправильные компиляторы, а ты говорил про правильные. А кто правильность определит?

Предлагаешь писать не на Си, а на языке «gcc-11 c -O1»

У Си много диалектов. Часть из них друг с другом взаимно несовместима. Если ты хочешь писать прогу, которая компилируется в правильно работающий бинарник (кстати, может ещё про разные платформы вспомним?) во всех из них без исключений - тебе придётся ОЧЕНЬ урезать возможности языка. Считаю такое неразумным (и думаю ты со мной согласишься). А вот дальше у нас разногласие: я считаю что разумно будет ориентироваться на имеющиеся общепринятые компиляторы, ты - на продукт чьей-то графомании, не имеющий даже референсной реализации. Понять такого не могу.

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

По твоему мнению,

  • Нужно ли в стандарте указывать, что происходит в случае записи значения по адресу, который выходит за границы объекта?
  • Нужно ли в стандарте указывать, что происходит в случае битового сдвига на >= бит, чем есть в типе? Т.е. например
    int x = 1;
    int y = x << 32;
    
shdown
()
Последнее исправление: shdown (всего исправлений: 1)
Ответ на: комментарий от eao197

А почему разработчик маленького кусочка программы берет на себя ответственность за завершение всей программы?

А почему ответственный за разработку программы принимает PR с unwrap?

вызвать unwrap – это нормально

Вызвать unwrap - это нормально. Так же, как вызвать std::abort() в C++, к примеру.

Cloudflare

И какие вообще альтернативы, когда ошибка в конфигурации?

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

А почему ответственный за разработку программы принимает PR с unwrap?

ХЗ. Может он воспитан на примерах из обучающих материалов по Rust-у, где unwrap на unwrap-е и unwrap-ом погоняет.

А может потому, что Rust настолько хорошо спроектирован, что в нем нет исключений. Ведь исключения – это же наследие жуткого C++, поэтому фу-фу-фу.

Вызвать unwrap - это нормально. Так же, как вызвать std::abort() в C++, к примеру.

От оно чё, оказывается. Не знал. Думал, что вызов std::abort в C++ – это крайняя мера.

И какие вообще альтернативы, когда ошибка в конфигурации?

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

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

важно как ведут себя конкретные компиляторы

С таким подходом ты не можешь написать программу, которая будет нормально работать с будущими компиляторами. А если пишешь по стандарту, то проблемы могут быть только в случае багов компилятора. Но это уже их проблемы, а не твои.

gcc поддерживает нормальное поведение знаковой арифметики

Допустим, со знаковой арифметикой разобрались, но что насчёт всех остальных UB?

ты говорил про правильные. А кто правильность определит?

Очевидно, что когда речь о программе, написанной на каком-то языке с определённой версией стандарта, то компилировать нужно компилятором, который поддерживает указанный язык и стандарт. Странно, что это нужно разъяснять.

У Си много диалектов. Часть из них друг с другом взаимно несовместима.

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

придётся ОЧЕНЬ урезать возможности языка

Урезать возможности стандарта не придётся. А если язык не устраивает, то почему бы не выбрать другой язык, вместо сомнительного диалекта?

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

ХЗ. Может он воспитан на примерах из обучающих материалов по Rust-у, где unwrap на unwrap-е и unwrap-ом погоняет.

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

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

Обычно, у сетевых сервисов умолчание - это или не делать ничего ни для кого, либо раздавать всем всё. Плохая идея в обоих случаях.

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

Ты так спрашиваешь, как будто стандартописатели собираются консультироваться у меня что им там писать. На вопросы прямо ответить не могу. Отвечу другое.

Нужно ли в стандарте указывать, что происходит в случае битового сдвига на >= бит, чем есть в типе?

На некоторых процах инструкция сдвига на чрезмерную битность оставляет от сдвига битность по модулю ширины регистра, например. А на каких-то - обнуляет регистр. В Си не принято прятать такие штуки от программиста, и соответственно оператор сдвига наследует процовое поведение. Как-то зафиксировать эту информацию, конечно, имеет смысл. Обзывать это UB - нет. Платформенно-зависимое поведение.

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

Очевидно, при записи за границу объекта происходит запись за границу объекта. Что из этого получится - зависит от расположения объектов в памяти и от операционной системы. Язык тут в целом ни при чём.

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

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

Время покажет.

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

С таким подходом ты не можешь написать программу, которая будет нормально работать с будущими компиляторами. А если пишешь по стандарту, то проблемы могут быть только в случае багов компилятора. Но это уже их проблемы, а не твои.

Пишу программы, которые нормально работают с нормальными компиляторами, в том числе будущими. Работу с дефективными компиляторами, чем бы они свою дефективность ни прикрывали (справками от си-комитета), гарантировать не могу.

Допустим, со знаковой арифметикой разобрались, но что насчёт всех остальных UB?

Нужен список. Но заранее скажу что многие так называемые UB на самом деле вовсе не UB, а платформо-зависимое поведение.

Очевидно, что когда речь о программе, написанной на каком-то языке с определённой версией стандарта, то компилировать нужно компилятором, который поддерживает указанный язык и стандарт. Странно, что это нужно разъяснять.

Тоже считаю что странно. Я пытался тебе разъяснить. Вот написана программа со стандартом -std=gnu89 -O0, компилировать соответственно нужно именно так.

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

Стандартов тоже много. Если ты про серию ISO Cxx, то это тоже диалекты Си. Да, они себя позиционируют как что-то высшее над диалектами, но это самоназвание и не более. И, как я уже писал, у них нет даже референсной реализации. А вот у GNU Cxx - есть (gcc). И то, что авторы шланга вынуждены, скрипя зубами, его тоже поддерживать - наглядное доказательство того, что это действительно существенная штука, а не чья-то локальная графомания.

Урезать возможности стандарта не придётся. А если язык не устраивает, то почему бы не выбрать другой язык, вместо сомнительного диалекта?

См. выше, unix v4 cc твой код скорее всего не скомпилирует, значит совместимость по крайней мере с одним диалектом ты уже потерял. Осталось только выбрать приоритетный. Мой выбор на данный момент - gcc.

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

На некоторых процах инструкция сдвига на чрезмерную битность оставляет от сдвига битность по модулю ширины регистра, например. А на каких-то - обнуляет регистр. В Си не принято прятать такие штуки от программиста, и соответственно оператор сдвига наследует процовое поведение. Как-то зафиксировать эту информацию, конечно, имеет смысл. Обзывать это UB - нет. Платформенно-зависимое поведение.

А вот на x86-64 обычные инструкции (sal/shl/sal/shr) берут сдвиг по модулю [кол-ва битов в ширине инструкции], а SIMD-шные расширения — зануляют при «переполнении». И мы хотим, чтобы компилятор где надо, мог использовать обычные инструкции, а где надо — SIMD-шные.

Как это описать в стандарте языка?

Очевидно, при записи за границу объекта происходит запись за границу объекта. Что из этого получится - зависит от расположения объектов в памяти и от операционной системы. Язык тут в целом ни при чём.

Да, очевидно. Но как нужно описать такую ситуацию в стандарте, если мы уже не можем ничего гарантировать в таком случае? Ну кагбэ это могло повредить структуры аллокатора памяти или ещё что-то подобное.

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

многие так называемые UB на самом деле вовсе не UB, а платформо-зависимое поведение.

Нет, UB - это то, что названо стандартом UB. Платформозависимое поведение - это unspecified behavior.

написана программа со стандартом -std=gnu89 -O0

Нет стандарта -O0, да и gnu - диалект, т.е. язык, не являющийся стандартным Си, почти вендор-лок.

unix v4 cc

Он не заявляет поддержку стандарта C23, поэтому никто от него и не ждёт компиляции современных программ.

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

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

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

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

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

Вы даже не представляете себе, как вы правы!!! Ладно бы оторванных от реальности, они и обсуждают в этом дурацком комитете вопросы, которые нормальный программист накогда в жизни даже не придумал бы. А почему? А потому что эти люди сидят на зарплате в группах разработки компиляторов. Им нужно, чтобы было проще реализовать, однозначно, и совместимо с предыдущим. Реальность их не интересует от слова совсем.

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

Как это описать в стандарте языка?

Я ж уже написал - «поведение зависит от платформы». И не надо пугать всякими UB бестолку.

Но как нужно описать такую ситуацию в стандарте, если мы уже не можем ничего гарантировать в таком случае?

Это не задача языка. Задача языка - сгенерировать машинные инструкции для выполнения запрошенного действия. Хочет программист писать за границу объекта - ок, пишем. Что будет дальше? Открывай отладчик и смотри. Это не UB. UB будет если компилятор вот этот код:

{ int a[10];
  a[11] = 5;
  printf("%d", a[11]);
  return 0;
}
превратит в
{
  return 0;
}
решив, что «да ну не может такого быть чтобы программа писала за границу массива». И вот это поведение целиком зависит от логики работы компилятора, а вовсе не от языка.

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

Нет стандарта -O0, да и gnu - диалект, т.е. язык, не являющийся стандартным Си, почти вендор-лок.

Да что ж ты такой упёртый? Сколько повторять?

C23

(речь была про ISO C23, я так понимаю) это тоже ДИАЛЕКТ. Надпись «стандарт», которую авторы данного документа туда вписали - это их личное мнение, и не более того. Никакого смысла она не добавляет. Я тоже могу награфоманить хоть десяток «стандартов Си», назову их «FIRK C23», «FIRK C24», «FIRK C25», «FIRK C3000» итд. И что? В лучшем случае, это будут мои личные спецификации (если я к ним компилятор напишу), в худшем - просто бесполезные фантазии (как у ISO). Кстати, компилятор таки планирую, но с временем на него печаль.

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

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

Это означает, что у IE5 был стандарт html-я. Более приоритетный чем стандарты от специализированных стандартописателей. Но тут есть отличие (возможно, субъективное): IE5-ный стандарт воспринимался скорее негативно, а вот GNU C - исключительно позитивно.

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

Это не задача языка. Задача языка - сгенерировать машинные инструкции для выполнения запрошенного действия.

Ну не языка, а компилятора. Язык ничего не генерирует.

Считаете, что оптимизирующие компиляторы не должны существовать? Всегда всё собираете с gcc -O0 чтобы компилятор выполнял свою задачу?

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

Хорошо, компилятора. А язык это спецификация того что должен делать компилятор.

Считаете, что оптимизирующие компиляторы не должны существовать?

Почему? Оптимизировать вполне можно. Но можно делать это без создания ненужных UB. Кстати, где-то на лор в последний вроде год приносили исследование, показавшее, что все эти UB-оптимизации по итогу дают средний эффект порядка процента.

Всегда всё собираете с gcc -O0 чтобы компилятор выполнял свою задачу?

Большинство кода действительно собираю с -O0. Другие -O ставлю там где важна разница в скорости между этими опциями. Это не так уж много мест. Если ставишь -O2 (а может уже и -O1, не помню), надо только не забывать сопровождать его -fno-strict-overflow -fno-strict-aliasing потому что -O2 эту пакость (signed UB и aliasing UB) включает по-дефолту.

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

Неизвестное распределение памяти - это не UB, я уже писал об этом. А запись за конец массива некоторые специально используют для разных целей. Одно из применений:

struct x {
  int a;
  int b;
  char str[1];
};

struct x *p;
p = malloc(sizeof(struct x)+10);
p->str[5] = 1;
С помощью malloc ты выделяешь кусок памяти больший чем формальный размер структуры, и пользуешься им как структурой у которой последний массив более длинный чем указано в описании. При этом с точки зрения компилятора это всё ещё остаётся записью за границу массива.

Применение «неизвестного распределения»:

void dump_stack(void) {
  size_t j;
  for(j=0; j<256; j++) {
    printf("%02X ", *(((unsigned char*)&j)+j));
    if((j%16)==15) printf("\n");
  }
}

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

Это не так уж много мест. Если ставишь -O2 (а может уже и -O1, не помню), надо только не забывать сопровождать его -fno-strict-overflow -fno-strict-aliasing потому что -O2 эту пакость (signed UB и aliasing UB) включает по-дефолту.

Убедил.

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

Ладно бы оторванных от реальности, они и обсуждают в этом дурацком комитете вопросы, которые нормальный программист накогда в жизни даже не придумал бы.

Ага. Например, чему равно выражение NULL - NULL в Си. Равно ли оно NULL? Нифига, это UB.

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

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

Ага, я и приносил. Поэтому сишных комитетчиков нужно слать в жопу. Сразу за сишными программистами.

P.S. Напомню, согласно даже самому свежему стандарту сишечки UB считаются в том числе незакрытые кавычки. Да, я серьёзно. А ещё отсутствие пустой строки в конце файла. И вот так тут во всём.

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

надо только не забывать

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

vbr ★★★★★
()
Ответ на: комментарий от firkax
struct x {
  int a;
  int b;
  char str[1];
};

Дядя, у тебя тут UB. Если ты начнёшь сравнивать указатели на разные элементы этого массива, компилятор может тебе поднасрать. Flexible array member пишется вот так:

struct x {
  int a;
  int b;
  char str[];
};

Появилось в C99, т.е. 26 лет тому назад.

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

на которых ты уже погорел

Ни на чём не погорал, включаю превентивно. А эти два ключа по-моему общеизвестные среди тех кто на Си что-то делает.

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

Ты бы дискуссию прочитал перед тем как отвечать. Обсуждалась как раз идиотия отдельных личностей, выдумывающих фейковые UB на ровном месте, и иногда даже пропихивающих их в компиляторы. Про синтаксис из второго кода я разумеется в курсе. Надо было наверно [3] там написать вместо [1] чтобы снизить шанс того что кто-то не так поймёт.

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

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

Проблема в том, что это UB не на ровном месте вылезло. Мой пример с NULL - NULL выше вышел из-за существования тегированных указателей, например. Т.е. может существовать реализация языка, где два разных указателя, оба технически кастуемые в (void*)0, будут иметь разное битовое представление.

Да, таких архитектур сейчас нет (фанаты CHERI, молчать!), но стоит заикнуться о нормальной стандартизации такой херни, как вылезают говнохранители со своими недоделанными DSP из 80х.

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

Не представляю зачем делать NULL-NULL. Точнее, (char*)NULL-(char*)NULL т.к. иначе это void* а над ним арифметику сложно определить.

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

Не представляю зачем делать NULL-NULL

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

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

Ты хочешь узнать, можно ли VLA использовать, можно ли писать размер массива уже после его объявления или можно ли использовать K&R синтаксис? В любом случае говнокод выходит, за который по лапкам молоточком давать надо.

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

В указанном примере нет VLA никаким боком.

А ЕСЛИ НАЙДУ?????!!!!!11

https://en.cppreference.com/w/c/language/array.html

Секция Variable-length array:

If the size is *, the declaration is for a VLA of unspecified size. Such declaration may only appear in a function prototype scope, and declares an array of a complete type. In fact, all VLA declarators in function prototype scope are treated as if expression were replaced by *.

void foo(size_t x, int a[*]);
void foo(size_t x, int a[x])
{
    printf("%zu\n", sizeof a); // same as sizeof(int*)
}
anonymous
()
Ответ на: комментарий от VIT

Поздно, уже тонны кода написано

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

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

Это не VLA, меньше графоманию читай. VLA это массив - локальная переменная с размером, вычисляемым во время выполнения. А тут это просто указатель на char (не массив!, собственно sizeof это наглядно показывает), вне зависимости от того что в квадратных скобках написано. Такой синтаксис аргументов-указателей считаю неудачным, он часто вводит в заблуждение новичков, но он есть уже очень давно, в C89 уже вроде был.

VLA же это изобретение комитетчиков для C99, но авторы компиляторов его сообща проигнорили, из-за чего комитетчики в C11 объявили его необязательным. Впрочем, компиляторы со временем поддержку таки добавили. Использовать не рекомендую - эта штука добавляет всякие неочевидные проблемы, лучше использовать явное alloca (для маленьких) или malloc (для больших) если нужен массив заранее неизвестного размера. Ещё для маленьких можно просто массив фиксированного размера объявить.

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

Это не VLA, меньше графоманию читай.

В стандарте написано, что это указатель на VLA.

https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

Пункт 6.7.5.2, в самом конце:

void fvla(int m, int C[m][m]); // valid: VLA with prototype scope
void fvla(int m, int C[m][m]) // valid: adjusted to auto pointer to VLA
{
...
anonymous
()
Ответ на: комментарий от anonymous

В стандарте написано,

Повторю:

меньше графоманию читай.

Что такое VLA я выше написал. А эти аргументы не могут быть VLA потому что VLA - это массив, а аргументы эти - указатели. Аргумент-массив передать невозможно, он везде, и в прототипе, и при передаче аргумента, конвертируется в указатель.

Впрочем, в контексте [m][m] получается «указатель на VLA». Но это влияет только на расчёт смещений при обращении к нему, никакого переменного выделения памяти (в чём суть VLA) тут не происходит.

А предыдущие примеры были с одним [m] там был указатель на просто char.

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

В стандарте написано,

Повторю:

меньше графоманию читай.

Что такое VLA я выше написал.

Пажжи пажжи… то есть, ты теперь утверждаешь, что твоё толкование Си – единственно правильное, а то что написано в стандарте и то чем руководствуются авторы компиляторов – это графомания? Тебе черепная коробка не жмёт там, случайно?

Впрочем, в контексте [m][m] получается «указатель на VLA». Но это влияет только на расчёт смещений при обращении к нему, никакого переменного выделения памяти (в чём суть VLA) тут не происходит.

Агааа, то есть ты уже согласен что тут есть VLA и есть указатель на него. Отлично! У нас прогресс!

anonymous
()