e2e4 писал(а):
Извините, существуют стандартное понятие "C-calls", "Pascal-calls" и т.д.
Вы точно не путаете стандарты и традиции? Лично для меня монополист ещё не является организацией по стандартизации.
e2e4 писал(а):
Если бы порядок параметров зависел от реализации компиляторов, фигня бы получилась при попытке написания программы, собираемой из объектников, скомпилированных с разных языков.
Ну что Вам сказать (вздох…) Даже объектные модули С++ из под Борланда, Антилопы Гну и Микромягких плохо собираются вместе. А уж разных языков… Соглашение о вызове — это последняя беда. Частенько нужно как-то среду (runtime) загрузить и проинициализировать. Вот тут как раз и начинается кино // И подливает в это блюдо остроты то, что все компиляторы пишутся людьми с большим Эго, которые считают себя самыми крутыми, свой язык — лучшим, а потому все должны подпрыгивать вокруг них.
e2e4 писал(а):
Почти на 100% можно быть уверенным, что разрядность int соответствует разрядности АЛУ процессора.
Это не так. Я уже объяснял, почему. На сегодняшний день я считаю
нормой памяти для
нового ноутбука 2ГБ, десктопа — 4ГБ. Это автоматически значит для меня 64-бит указатель, 32 бит int.
e2e4 писал(а):
Малюсенькое, не имеющее к делу замечание: INTPTR лучше определить через typedef.
Я демонстрировал
победный стиль, а не то, что я бы написал в реальном коде. Так что, см. ниже.
Кроме того, эта тема посвящена подобному коду, так что пример показался мне уместным.
e2e4 писал(а):
Вообще-то, не уверен в корректности возвращения указателя на константную строку, определяемую в функции, из которой этот указатель возвращается,
Это-то как раз корректно. В коде много других огрехов: например, стандарт не гарантирует, что (int) NULL == 0
, есть неявное преобразование int ** в int* и т.п.
А константная строка находится в статической памяти, поэтому такой номер законен.
Вообще говоря, в С есть много радостей. В частности, выражение
Код:
char* a = "победа!\n"; a[0] = ' '; a[1] = ' '; printf("победа!\n");
вполне законно. Что будет происходить дальше, сильно зависит от реализации. В частности, некоторые реализации, зная о практике модификации литералов, предлагают режим компиляции, при котором каждая литеральная строка используется только однажды.
e2e4 писал(а):
действительно использовалось 2 последовательных вызова ф-ии
Если предполагать, что адрес может быть со знаком (конкретно, чтобы меня не обвиняли в том, что так не бывает: Inmos'овские транспьютеры), то может понадобиться три вызова.
e2e4 писал(а):
Т.е. с указателями определены операции сложения/вычитания без явного их приведения к целому типу. Результат операции - целое число.
(1) См. выше (
tolstopuz).
(2) Определены операции сложения указателя с целым и вычитания двух указателей. Сложения указателей нет.
(3) Кроме того, результат вычитания — не целое число, а число типа ptrdiff_t, который обязан быть знаковым, но не обязан быть int. Более того, никто не гарантирует (хотя это, разумеется, маловероятно), что при вычитании указателей не произойдёт переполнение. Не может быть? Может! Представьте себе, что Вы пишите программу распределения памяти, которой принадлежит почти вся память в начальный момент.
e2e4 писал(а):
я блоки не пишу, я ими думаю
Эт' хорошо. Существует два ответа:
1) потребность в синтаксических блоках резко уменьшается, когда каждая ветка ветвления, каждое тело цикла автоматически становится блоком. Приведу пример из С++:
Код:
for (int x = 0; ;) {break;}
for фактически определяет блок (и время жизни переменной). Но в С++ это — ублюдок (в первоначальном смысле этого слова), а представьте себе, как это выглядит, когда логично проведено через весь язык…
2) такой блок (имеющий законченную семантику) логично выделить в процедуру.
3)
Так не отнимает у Вас блок никто. Просто он Вам нужен гораздо реже.