Страницы

Поиск по вопросам

четверг, 4 октября 2018 г.

Циклы и прочие штуки, взятые в { … }

Здравствуйте! Волнует такой вопрос. Есть в с++ такие вот скобки {}. Если в методе, в них объявить переменную как тут: void funct(){ int g=0; { int g=0; } } то компилятор не будет ругаться. Почему? Если объяснить на языке ассемблера то что произойдет? Произойдет вызов функции с передачей всех переменных доступных верхней функции в {}? если да, то как передадутся переменные, в стеке? Для чего вообще может быть допустима приведенная выше конструкция? И вот еще. Вот этот символ ";" означает конец операции, например int t=a+b;. А что он выполняет? почему его можно ставить так: void f(){ ; } или void f(){ }; и ошибки не будет? Что делает компьютер, когда натыкается на ;? Спасибо.


Ответ

{....} - это блок кода и он может быть вставлен везде, где можно вставить одиночную строку. Вас ведь не смущает код: if (....) doSmth(); и if (....) { doSmth(); } Но у этих скобок есть одна особенность - они объявляют новую область видимости. void funct(){ int g=0; { int g=0; // это другая переменная g, она имеет другой адрес! // предыдущая g не доступна по своему имени до закрывающей фигурной скобки. } // а здесь снова доступна первая переменная. } На уровне ассемблера это выглядит так funct(): push rbp mov rbp, rsp mov DWORD PTR [rbp-8], 0 ; первая g mov DWORD PTR [rbp-4], 0 ; вторая g pop rbp ret как передадутся переменные, в стеке? как обычно. Хотя никто не мешает компилятору проанализировать и сделать хорошо. Для чего вообще может быть допустима приведенная выше конструкция? например для любителей длинных функций, когда хочется добавить ещё сотню строк, а переменные (имена) закончились. Но если серьезно, то подобные конструкции используются постоянно - циклы, условия. Вот этот символ ";" означает конец операции, например int t=a+b;. А что он выполняет? он выполняет декоративную роль для программиста. Это синтаксический сахар. Но компилятор может пользоваться им в том случае, если в коде много ошибок, что бы хотя бы как то разделять операторы. Вот в Go точку с запятой можно пропускать, когда и так понятно, что она там должна быть. В ассемблерном коде она никак не отображается.

Комментариев нет:

Отправить комментарий