powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Ссылка на переменные, потерявшие видимость
25 сообщений из 37, страница 1 из 2
Ссылка на переменные, потерявшие видимость
    #39284740
nojava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Собственно вопрос. Насколько легален код ниже?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
#include <stdio.h>

int main()
{
    int *p1, *p2;
    {
        int a[1025] = {1};
        p1 = a;
        int c = 14;
        p2 = &c;
    }
    int b = 12;

    printf("%d %d %d", *p1, *p2, b);

    return 0;
}



как ни странно, но везде работает, выводит 1 12 14, хотя это несколько неожидаемое поведение - по идее переменные a и с, потерявшие видимость, могут быть заюзаны следующей переменной b.

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


весь сыр бор из-за попытки заменить alloca() на VLA, чтоб не тянуть зависимости из malloc.h
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284760
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nojavaНасколько легален код ниже?
Совершенно нелегален.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284768
nojava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovnojavaНасколько легален код ниже?
Совершенно нелегален.


ссылка на стандарт и/или доку?
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284779
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284782
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Похоже компиляторы отслеживают подобные выстрелы в ногу
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
int main()
{
	int c = 0;
	int *p1, *p2, *p3;
	{
		int a[100000] = { 1 };
		printf("%d\n", a[0]);
		p1 = a;
		//p1 = &c; //убрать каммент и перестанет вылетать из-за нехватки места в стэке
	}
	{
		int a[100000] = { 2 };
		p2 = a;
	}
	{
		int a[100000] = { 3 };
		p3 = a;
	}

	printf("%d %d %d", *p1, *p2, *p3);

	return 0;
}

...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284784
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nojavaНасколько легален код ниже?
Согласно стандарта как в С так и в С++ - это UB.

С практической точки зрения проблема с использованием вышедших из видимости переменных заключается в том, что они размещены на стеке, и компилятор считает что они не используются, а значит что угодно с ними делать.
В каких-то простейших случаях может и работать. Но мы то знаем что у вас не бывает простых программ )))

Вот например GCC с оптимизацией такое не нравится, а без - работает.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
    int *p1, *p2;
    {
        int a[1] = {1};
        p1 = a;
    }
    {
        int a[1] = {2};
        p2 = a;
    }

    printf("%p=%d %p=%d\n", (void*)p1, *p1, (void*)p2, *p2);



ЗЫ. Удачи тем кто будет за вами код поддерживать
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284786
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://en.cppreference.com/w/cpp/language/storage_duration
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284790
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyВот например
Упростил пример
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
    int *p1;
    {
        int a[1] = {1};
        p1 = a;
    }

    printf("%p=%d\n", (void*)p1, *p1);
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284807
nojava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyЗЫ. Удачи тем кто будет за вами код поддерживать

да нет никакой удачи, это я просто на devtoolset-4 не переключился, пока "тестировал".
старый gcc 4.4 при O3 никаких катастроф не показывал, потому я и удивился, может это такой-же tradeoff, как и memcpy несоответствие стандартам.


удачи это скорее тем, кто перейдет на gcc 5.x без регрессионных тестов (алиасинг там еще цветочки).

в целом вопрос снят, хотелось конечно получить невидимость имени символьного массива в asserta() заменителе, но это скорее уже перфекционизм
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284811
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nojavagcc 5.x
То что вы не смогли в 4.х придумать тесткейс, не значит что в реальном коде этой проблемы нет.

Так что таки да, удачи
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284814
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nojava,
абсолютно нелегален.
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284818
nojava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskynojavagcc 5.x
То что вы не смогли в 4.х придумать тесткейс, не значит что в реальном коде этой проблемы нет.

Так что таки да, удачи
чего чего я не смог? в каком еще реальном коде?

я вроде популярно сказал, что в gcc 4.4->5.x сильно поменялось поведение в UB и возможно многие этого не ожидают,
лишь -Wall в 5.1 пока помогает такое отловить (даже coverity не пришлось подключать).

а о каком реальном коде ты сейчас - прямо загадка
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284822
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nojavaа о каком реальном коде ты сейчас - прямо загадка
том, в котором вы пытались
nojavaзаменить alloca() на VLA

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

Эти же люди обычно полагают, что они понимают какой код генерит компилятор С (в отличие от С++).

Милые, забавные вобщем люди
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284827
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyЭти же люди обычно полагают, что они они понимают какой код генерит компилятор С
Кстати, обращаюсь этим людям. На этом форуме их несколько.
Вот код. В GCC 4.9.2 x64 в режиме отладки он печатает все верно, а в релизе с -03 печатает мусор после =.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
    int *p1;
    {
        int a[1] = {1};
        p1 = a;
    }

    printf("%p=%d\n", (void*)p1, *p1);



Поскольку "при компиляции С генерится простой и понятный код", то вам не составит труда не заглядывая в дизассемблер пояснить, почему с оптимизацией мусор, а без - нет.
Ну и заодно, если заменить printf на этот, то объясните почему это в любом случае работает, независимо от оптимизации.
Код: plaintext
1.
    printf("%d\n", *p1);



Хочу убедиться, что действительно С проще чем С++ )))
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284840
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskyобъясните
Всерьёз хочешь это слышать или прикалываешься?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284853
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovВсерьёз хочешь это слышать или прикалываешься?
Всерьез
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284856
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nojavaDimitry Sibiryakovпропущено...

Совершенно нелегален.


ссылка на стандарт и/или доку?

Раздел 3.8
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284857
nojava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyПоскольку "при компиляции С генерится простой и понятный код", то вам не составит труда не заглядывая в дизассемблер пояснить, почему с оптимизацией мусор, а без - нет.
и в чем проблема? включи -O4 -fstack-reuse=none и у тебя снова будет не мусор, деццкий сад, господи.


Anatoly MoskovskyНу и заодно, если заменить printf на этот, то объясните почему это в любом случае работает, независимо от оптимизации.
нет, не работает, вместо 1 показывает 0
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284860
nojava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivnojavaпропущено...


ссылка на стандарт и/или доку?

Раздел 3.8

забей, все уже найдено.
отдельно было забавно почитать про поведение goto при VLA, этого я к примеру не знал. хотя догадывался (просто не использую goto)
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284870
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nojavaи в чем проблема? включи -O4 -fstack-reuse=none и у тебя снова будет не мусор, деццкий сад, господи
У меня нет проблемы. Я такой код не применяю. И вообще в первый раз из этого топика узнал о том, что кому-то вообще может прийти в голову спрашивать насколько такой код легален .

Вопрос был не как обойти на костылях, а какой код генерится.

nojavaнет, не работает, вместо 1 показывает 0
Так вот и объясните, почему в зависимости от опций и версий работает по-разному.
Это же просто С, все очевидно )))
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284872
nojava
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskynojavaи в чем проблема? включи -O4 -fstack-reuse=none и у тебя снова будет не мусор, деццкий сад, господи
У меня нет проблемы.
и в чем проблема объяснить поведение?

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

Anatoly Moskovskynojavaнет, не работает, вместо 1 показывает 0
Так вот и объясните, почему в зависимости от опций и версий работает по-разному.
Это же просто С, все очевидно )))
С и C++ используют один и тот-же backend, нет никакой разницы в поведениях.

С проще чем C++ просто потому, что в C +, - и << >> всегда означают одно и то-же, за выражением a + b не может скрываться вызов кода форматирования корневого раздела.

потому С всегда очевиден, в отличие от.
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284879
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nojavaС и C++ используют один и тот-же backend, нет никакой разницы в поведениях.
Причем здесь С++.
Объясните поведение кода на С, который выше приведен, если конечно сумеете
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284880
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyТак вот и объясните, почему в зависимости от опций и версий работает по-разному.

Потому что lifetime нельзя сужать, но можно расширять. Точнее можно забить на освобождение
уже ненужной памяти. Дальше идут особенности размещения переменных в стэке, которым каждый
компилятор распоряжается по-своему. Недавно, например, я узнал, что MSVC и GCC их
располагают, фактически, зеркально противоположно.

Ну а по последнему вопросу: просто не хватило количества параметров у printf() чтобы
затереть тот кусок, где был a.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284881
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovПотому что lifetime нельзя сужать, но можно расширять.
Я знаю почему нельзя так делать.
Вопрос был на тему какой код сгенерит компилятор С, ответ на который обосновал бы слова "потому С всегда очевиден". )))

Dimitry SibiryakovНу а по последнему вопросу: просто не хватило количества параметров у printf() чтобы
затереть тот кусок, где был a.
Вот тут столько эе параметров, как в первом, а эффект не виден.
Код: plaintext
1.
printf("%p %d\n", NULL, *p1);
...
Рейтинг: 0 / 0
Ссылка на переменные, потерявшие видимость
    #39284883
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyAnatoly MoskovskyЭти же люди обычно полагают, что они они понимают какой код генерит компилятор С
Кстати, обращаюсь этим людям. На этом форуме их несколько.
Вот код. В GCC 4.9.2 x64 в режиме отладки он печатает все верно, а в релизе с -03 печатает мусор после =.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
    int *p1;
    {
        int a[1] = {1};
        p1 = a;
    }

    printf("%p=%d\n", (void*)p1, *p1);



Поскольку "при компиляции С генерится простой и понятный код", то вам не составит труда не заглядывая в дизассемблер пояснить, почему с оптимизацией мусор, а без - нет.Если кратко, то все что не влияет на переменные во внешней области видимости - может быть выкинуто оптимизатором нафиг как ненужное. В данном случае: p1 не определено перед блоком, и ссылается на более не существующую переменную после блока, а значит опять не определено. Вывод: весь блок можно выкинуть.

Anatoly MoskovskyНу и заодно, если заменить printf на этот, то объясните почему это в любом случае работает, независимо от оптимизации.
Код: plaintext
1.
    printf("%d\n", *p1);

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

Anatoly MoskovskyХочу убедиться, что действительно С проще чем С++ )))Проще. Но ты не там ищешь доказательства простоты.
...
Рейтинг: 0 / 0
25 сообщений из 37, страница 1 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / Ссылка на переменные, потерявшие видимость
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]