LINUX.ORG.RU

Какие правила языка C++ здесь используются?

 ,


0

3

Вот имеем два примера:

const int x = 5;

int main(int argc, char** argv)
{
    int x = x;
    cout << x;
    return 0;
}
Результат 0.

const int x = 5;

int main(int argc, char** argv)
{
    int y = x;
    cout << y;
    return 0;
}
Результат 5.

Я бы мог это понять, если бы небыло третьего примера:

const int x = 5;

int main(int argc, char** argv)
{
    int x[x];
    cout << sizeof(x) / sizeof(int);
    return 0;
}
Результат 5.

Вот. Какие свойства/правила языка обеспечивают такое поведение?

★★★★★

Последнее исправление: Xintrea (всего исправлений: 1)

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

В твоем коде и не глобальная переменная. У тебя глобальная явно инициализируется 5. Локальные перменые не инициализируются.

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

Скорее всего это UB. Я не помню стандарт. Тут рассматривают, говорят что UB https://stackoverflow.com/questions/14935722/does-initialization-entail-lvalu...

Почему это может быть не UB: Я скомпилировал этот пример clang с флагами

-fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer
И с библиотеками
-lubsan -lasan
Но он не показал ошибок... Обычно он хорошо показывает UB...

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

Глобальные переменные всегда инициализировались, в частности int нулём.

Он, видимо, в общем говорил, не про конкретные примеры.

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

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

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

А вот что говорит стандарт сишечки ISO/IEC 9899:201x N1570 (у меня под рукой только драфт от April 12, 2011).

If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate. If an object that has static or thread storage duration is not initialized
explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules,
and any padding is initialized to zero bits;
— if it is a union, the first named member is initialized (recursively) according to these
rules, and any padding is initialized to zero bits;
fluorite ★★★★★
()

int x = x; это выражение объявляет переменную и присваивает ей значение (на самом деле инициализирует). При этом это объявление скрывает предыдущее объявление x, которое на самом деле остается доступным через ::x. Более того, не работает даже такая запись

int x{x};
, однако вот такой вариант, почему-то работает:
struct Test
{
    Test(int x)
        :x{x}
    {}
    int x;
};

i-rinat, давай поддтягивайся

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

А, ну да. Ладно, я, наверное, вообще тебя запутал. Извиняюсь, если что.

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

Глобальные переменные всегда инициализировались, в частности int нулём.

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

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

Решил посмотреть что другие компиляторы пишут

Такое проще всего смотреть на божественном сайте https://godbolt.org/ (только нужно вытащить окошко с предупреждениями компилятора).

https://godbolt.org/g/B5G6sG

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

То есть, все-таки UB, а не декларатор—инициализатор, как писали здесь?

UB при инициализации нового x, а про скрывание старого x новым все верно.

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

thread-local, те, которые перед main в главном треде. Локальные да — это автоматические и они инициализируются мусором (тем, что было в памяти, которая потом стала стеком).

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

Кстати, clang не инициализирует нулём.

Чтение из неинициализированной локальной переменной - это неопределенное поведение (UB). Компилятор может делать что угодно, даже выбросить весь код, который обращается к этой переменной (или вообще весь код единицы трансляции) или сделать abort(). Что нагенерит компилятор - зависит от компилятора и его параметров (в первую очередь оптимизации). Раньше я думал, что без оптимизации компилятор оставит переменную в неинициализированном состоянии и сделает чтение «мусора» из нее, но по результатом предыдущего топика со странными switch, я понял, что даже без оптимизации компилятор с случае UB может начать выкидывать код.

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

Чтение неинициализированной переменной - это UB. Загоните код

#include <cstdio>

void test()
{
    bool flag;
    if( flag )
        puts( "true" );
    else
        puts( "false" );
}
в godbolt и поиграйтесь с флагами компиляции (оптимизации) - увидите результат.

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

thread-local, те, которые перед main в главном треде.

А если не в главном треде, но thread_local, а если просто static в единице трансляции (т.е. с внутренним связыванием).

P.S. Нефиг сюда тащить вполне конкретный термин (thread_local), который сюда не относится. Для него, кстати, тоже есть правила инициализации, но объяснить их простым обнулением .bss (тупо memset() перед main()) уже не получится, потому что thread_local переменная может появится из dll, который подгружен после начала работы main() из какого-нибудь плагина.

anonymous
()

Для изучения C++ есть два полезных курса от питерских парней:

https://stepik.org/course/7

https://stepik.org/course/3206 (на самом деле продолжение первого)

У них куча недостатков, но суть проста - после их прохождения знаний и навыков сильно прибавляется. Для решения тестов и заданий придется много информации искать в интернете, но какой именно информации станет понятно во время прохождения теста (решения задачи). После решения задачи - просмотр других решений обязателен (+30% к знаниям).

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

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

В этом, конечно же, ничего плохого нет, но выдавая что-то за то, чем оно не является - ты внушаешь пацанам ложные надежды на то, что прохождение курса как-то сильно повышает уровень понимания. Тем самым ты демотивируешь пацанов развиваться дальше, ведь оно уже.

Всё просто

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

Как UB и декларатор—инициализатор исключают друг друга?

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

Я так и не понял из твоего длинного сообщения есть польза от предложенных курсов или нет?

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

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

Я так и не понял из твоего длинного сообщения есть польза от предложенных курсов или нет?

Я нигде и не отрицал их полезности, я говорил совершенно о другом, а переоценивании.

Про демотивацию развиваться дальше после прохождения курсов - это ты сам придумал.

Нет, это я не сам придумал. Я не зря в той теме поднял срач, и ты должен был увидеть, сколько существует мнящих из себя экспертов, и что они представляют из себя реально. Хотя невероятную тупость и упоротость той бабы - сложно переплюнуть, но всё же.

И всё это - жертвы, людям не интересно и не нужно разбираться в чём-то - им нужно признание. Им нужно соответствие. Дали еду, прошел курс - уже всё, у 95% плывёт от этого крыша и они уже эксперты во всём. Сваял хелворд и ты уже эксперт.

Всё это проявлялось и в той теме, и в сотнях других. Ты можешь в ту же тему про новое кулл-ide и посмотреть на то, что человек вроде как и сделал что-то полезное и 5 звёзд нафлудил, но табуретка табуреткой, и единственно, что подобных спасает от позора - это другие подобные, которые всё это чистят.

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

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

Хотя тут те же проблемы, и в их поведении есть смысл. Соответствие и признание работают в две стороны. И если твоё окружение верит в то, что подобные знания - это знания, то если ты не знаешь - плохо, но плохо не только это - плохо и то, если ты знаешь и понимаешь больше.

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