LINUX.ORG.RU

[C++] Синтаксис

 


0

1
printf("%d != %d, why?\n", sizeof('"')["'"], (sizeof("'"))["]\"\0["]);

Как такая конструкция возможна с точки зрения синтаксиса языка? (Код комплируется и выполняется)

★★

Боюсь запускать, вдруг там rm -rf завуалированный.

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

Мдя... Получается, это такое хитрое взятие sizеof-того элемента строки в квадратных скобках? Или я не прав?

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

А... Ясно, не знал такой фишки. Спасибо.

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

Еще можешь удивиться с этого:

int xx[]={1,2,3,42};
printf("%d\n",3[xx]);
Но это более известно.

staseg ★★★★★
()

С примером топикстартера в общем всё понятно, но я один момент понять не могу. Почему

sizeof('"')["'"] == 1
но
1["'"] == 0

"'"[sizeof('"')] == 0
?

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

Ответ неверный :)

Вот правильный:

int main()
{        
printf("%d\t|\t%d\n", sizeof('"'), (sizeof('"')));
printf("%d\t|\t%d\n", sizeof('"')[" "], (sizeof('"'))[" "]);
}
Скомпилировалось, запуск...
1       |       1
1       |       0
legolegs ★★★★★
()
Ответ на: комментарий от legolegs

>sizeof('«')[»'«] == 1

Если ты сделаешь sizeof('»')[0], получишь фейл. Если присмотреться, имеет место двойной финт ушами с квадратными скобками: данное выражение эквивалентно sizeof(«'»)['«'], что эквивалентно sizeof(»'«['»']). Hint: seq[offs]==offs[seq].

1[«'»] == 0

Тут просто. Второй по счету символ в строке «'» - \0 (== 0).

«'»[sizeof('«')] == 0

Аналогично.

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

> Ответ неверный :)

с чего это? (sizeof('«'))[» «] - вот тебе завершающий 0

aho
()

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

1. Как работает оператор x[y]? Это на самом деле запись для (x+y). Работает это потому, что один из операндов - указатель или массив (массив обрабатывается как указатель на его нулевой элемент). Сложение указателя и целого даёт новый указатель, который, если считать в байтах, больше старого на y*sizeof(тип, на который указывает x). Но это уже не важно, а важно то, что мы работаем с суммой, а от перемены мест слагаемых сумма не меняется. Поэтому в записи x[y] x и y можно менять местами. Но один из них обязан быть указателем или массивом, конструкции типа 2[3]==5 всё-таки запрещены.

2. Строковый литерал («hello world») - это массив, поэтому можно писать «string»[1]=='t'. И 1[«string»]==t тоже, см п. 1.

2.1 «'» и «]\»\0[" - тоже строковые литералы aka массивы char'ов. Хоть и страшненькие.

2.2 Строковый литерал заканчивается нулём. «'» - это массив из двух байт: 39 и 0. sizeof(«'»)==2

3. Символьный литерал (если я правильно вспомнил термин) - это 'буква'. '«'==34. В си++ символьные литералы имеют тип char и размер sizeof('»')==1. В си тип int и размер когда как, но больше 1. 2,4,8 - зависит от архитектуры и компилятора (кстати, если тебе кто скажет, что «да почти всегда 4, не парься чувак» - плюнь ему в лицо). В си сабжевый код напечатает иное.

4. То, на чём я накололся: sizeof - это не функция и не макрос. Это ключевое слово и приоритет у него _меньше_, чем у []. Код sizeof('«')[»'«] считает размер ('»')[«'»] (который в си++ равен 1).

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

>1. Как работает оператор x[y]? Это на самом деле запись для (x+y)

*(x + y)

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

Это понятно. Смутило в основном то, что я думал, что operator[] принимает аргументом только значения целого типа, а здесь он без явного преобразования спокойно взял указатель, что, как я думал, в С++ должно давать по меньшей мере предупреждение. А оказалось, что еще и можно местами менять аргумент с объектом, что логично с точки зрения сложения, но нелогично с точки зрения синтаксиса.

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

> Как такая конструкция возможна с точки зрения синтаксиса языка?

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

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

> Вполне нормальная конструкция же.

Такая конструкция является нормально только для говнокодеров, для всех остальных она ненормальная.

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

> Ну это потому что язык говно - вот он и позволяет подобные конструкции.

Такая конструкция конечно же минус языку, но сам язык говном от этого не становится.

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

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

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

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

>sizeof(smth[x]) эквивалентно sizeof(smth)[x]

Не знал этой фишки. А можно ссылку на стандарт?

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

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

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