LINUX.ORG.RU
ФорумTalks

[cpp]i++ + ++i


0

0

Привет, многоуважаемый all.

void f(const int &c)
{
int *p = (int *) &c;
*p = 10;
printf(«%i\n», *p);
printf(«%i\n», c);
}


int main(int argc, char *argv)
{
const int c = 2;
f(c);

printf(«%i\n», c);
return 0;
}

Выводит:
10
10
2

Почему?


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

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

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

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

Хм... И что происходит при вызове? Копирование? А чем тогда это отличается от передачи по значению? О_о

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

>если ассемблер смотреть - он вместо честной константной переменной в мейне подставляет в принт цифру 2. доколе???

А ты не думал, что компилятор таки может оптимизировать код???
А в мейне он точно знает, что переменная при вызове функции не изменится (ИБО const).

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

а вас никогда-никогда не было желания кастануть константный указатель к обычному???

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

xnick
() автор топика

передавай указатель, извращенец

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

Соб-сно это и не оптимизация: вместо переменной-константы (а она по программе не изменяется) подставить ее значение.

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

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

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

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

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

>а вас никогда-никогда не было желания кастануть константный указатель к обычному???

Не надо этого хотеть ©

Deleted
()

Жопой чую, что это из какого-то индускодовского проекта, в котором не заработал данный костыль.

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

а вот так (заменить int на char *)

void f(const char const * &c)
{
char * *p = (char * *) &c;
*p = (char *)10;
printf(«%i\n», *p);
printf(«%i\n», c);
}


int main(int argc, char *argv)
{
const char const *c = (char *)2;
f(c);

printf(«%i\n», c);
return 0;
}

получаем
10
10
10

Чудны дела твои, господи.

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

>стандарт

Я сомневаюсь, что в госте на двери написано что-то вроде «если дверь встречает на своём пути яйца, то её поведение зависит от реализации».

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

>Я сомневаюсь, что в госте на двери написано что-то вроде «если дверь встречает на своём пути яйца, то её поведение зависит от реализации».

а я сомневаюсь, что если закрыть дверь, потом представить что она открыта, потянуть за ручку - и дверь откроется.

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

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

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

вопрос чисто технический, и довольно конкретный =)

а что до яиц - можно прищемлять свои (на любителя), а можно и чужие, тут как повезет.

уже писал, что «это плохой стиль». продолжать дискуссию в данном направлении мне бы не хотелось.

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

>вопрос чисто технический, и довольно конкретный =)

И на него ответили. Поставь галочку в треде и перестань писать хрень не в тему.

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

Раз ты представляешь дверь открытой, то компилятор при поступлении команды «посмотреть, что за дверью» подсовывает тебе фотку, которую он сделал минуту назад, потому что на этой двери большими буквами написано «ЗА НЕЙ НИЧЕГО НИКОГДА НЕ МЕНЯЕТСЯ».

Yareg ★★★
()

Можно было бы в main просто вызвать f(2) и получить те же 10 - 10. Ни на какие мысли не наталкивает?

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

давай ты лучше нажмешь кнопочку «игнор»

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

>Раз ты представляешь дверь открытой, то компилятор при поступлении команды «посмотреть, что за дверью» подсовывает тебе фотку, которую он сделал минуту назад, потому что на этой двери большими буквами написано «ЗА НЕЙ НИЧЕГО НИКОГДА НЕ МЕНЯЕТСЯ».

Если бы я писал компилятор, я бы честно размещал константные переменные в константной области памяти, и подобные примеры вызывали бы рантайм еррор.

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

>Можно было бы в main просто вызвать f(2) и получить те же 10 - 10. Ни на какие мысли не наталкивает?

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

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

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

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

Там располагаются сами строки, которые в кавычках. А переменная хранит указатель и располагается в стеке.

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

>Если бы я писал компилятор, я бы честно размещал константные переменные в константной области памяти, и подобные примеры вызывали бы рантайм еррор.

И я очень рад, что gcc писал не ты. Компилятор делает так, как считает лучше, а не так, чтобы случаи «прищемления» работали «правильно» по мнению ув. Василия Пупкина.

Pavval ★★★★★
()

Внезапно, const int в c++ вычисляется на этапе компиляции (если может) и подставляется во все вхождения, это описано в стандарте.

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

Т.е. это стандартный способ задания констант вычисляемых при компиляции, как enum { } в c99, например.

Adjkru ★★★★★
()

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

Legioner ★★★★★
()

У Страуструпа вот что написано:

«Объект типа без конструктора или деструктора, который имеет спецификацию const, может быть помещен в память, доступную только по чтению. Попытка записи в любую часть такого объекта или приведет к особой адресной ситуации, или пройдет бесследно, как если бы объект не имел спецификации const.»

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

Это в R.7.1.6 Спецификация типа, Справочное руководство по C++.

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

> если взять значения указателя, адрес константы из функции f и адрес константы из маина - все эти адреса совпадут. а теперь самое интересное - как может по одному и тому же адресу находиться разные числа? если ассемблер смотреть - он вместо честной константной переменной в мейне подставляет в принт цифру 2. доколе???

Тебе надо сделать:

1) убрать const

2) добавить volatile

3) Учить уроки.

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

> по которому получается именно 10, 10, 2 или неопределенное поведение.

стандарт С++ такое допускает

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

>Если бы я писал компилятор

Хорошо, что ты не пишешь компиляторы. Итак всё тормозит, а если ещё и компиляторы искусственно ухудшать...

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