2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2, 3, 4  След.
 
 struct S* x;
Сообщение29.10.2021, 07:52 


06/04/18

323
Используется синтаксис C++
struct S {
    struct S* x;
}


Это непохоже на вложенный тип данных в структуре, поскольку повторно используется имя S. Это не объявление указателя на S, иначе было бы просто S* x;. Тогда в чём смысл данного кода, и что он делает ?

 Профиль  
                  
 
 Re: struct S* x;
Сообщение29.10.2021, 08:04 
Аватара пользователя


28/10/21
100
Qlin в сообщении #1536825 писал(а):
Это не объявление указателя на S, иначе было бы просто S* x;.


Код скорее всего написан на языке С. В языке С объявление указателя на тип struct S - это именно struct S *, а никакой не S *.

Более того, и в языке С++ вы имеете полное право написать struct S * вместо S *. Никто вам этого не запрещает.

Так что откуда вы взяли свое "иначе было бы просто S* x" - не ясно. С чего бы это вдруг?

Qlin в сообщении #1536825 писал(а):
Тогда в чём смысл данного кода, и что он делает ?


Это код ничего физически не "делает". Это лишь объявление типа. Объявляется структурный тип, содержащий указатель на такой же структурный тип.

 Профиль  
                  
 
 Re: struct S* x;
Сообщение29.10.2021, 09:05 


10/04/12
705
Qlin в сообщении #1536825 писал(а):
Тогда в чём смысл данного кода, и что он делает ?


Это объявление указателя в стиле, который совместим с си.

 Профиль  
                  
 
 Re: struct S* x;
Сообщение29.10.2021, 18:07 


06/04/18

323
Используется синтаксис C++
#include <iostream>

struct S {
    struct S* x;
} S0;

int main() {
    std::cout << S0.x->x;
}
Почему данная программа ничего не выводит в консоль ? Разве она не должна вывести хотя бы какое-то мусорное значение, хранящееся в памяти ?

 Профиль  
                  
 
 Re: struct S* x;
Сообщение29.10.2021, 18:16 
Заслуженный участник
Аватара пользователя


16/07/14
9202
Цюрих
Qlin в сообщении #1536901 писал(а):
Почему данная программа ничего не выводит в консоль ? Разве она не должна вывести хотя бы какое-то мусорное значение, хранящееся в памяти ?
Она вообще ничего не должна. Тут неопределенное поведение - вы читаете из неинициализированной переменной. Компилятор имеет полное право заменить эту конструкцию на что угодно, хоть на форматирование диска.
Скорее всего компилятор понимает, что S0.x не инициализировано, делает из этого вывод, что выполнение до строчки, из неё читающей, не дойдет, и честно эту строчку выкидывает.
(кстати какой компилятор? у меня этот код ожидаемо сегфолтится)

 Профиль  
                  
 
 Re: struct S* x;
Сообщение29.10.2021, 18:17 
Аватара пользователя


28/10/21
100
Qlin в сообщении #1536901 писал(а):
Почему данная программа ничего не выводит в консоль ? Разве она не должна вывести хотя бы какое-то мусорное значение, хранящееся в памяти ?


Множество причин:

1. "Должна"? Программа имеет неопределенное поведение. Она никому ничего не "должна".
2. Потому что программа, вывод которой в текстовый поток не завершается переводом строки, вообще не обязана ничего никуда выводить.
3. Потому что памяти не существует, пока вы ее сами не распределите (что особенно хорошо видно на платформах с виртуальной памятью). А раз не существует памяти, то не существует и никакого "мусорного значения".

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

 Профиль  
                  
 
 Re: struct S* x;
Сообщение29.10.2021, 18:24 
Заслуженный участник
Аватара пользователя


16/07/14
9202
Цюрих
TheRuinedMap в сообщении #1536905 писал(а):
Потому что программа, вывод которой в текстовый поток не завершается переводом строки, вообще не обязана ничего никуда выводить
Почему? При уничтожении cout позовется flush. И причем тут перевод строки?

 Профиль  
                  
 
 Re: struct S* x;
Сообщение29.10.2021, 18:26 
Заслуженный участник


18/09/21
1764
S0.x - это указатель (т.е. адрес). Но Вы его не инициализировали. Там лежит мусор или возможно ноль.
Когда Вы пытаетесь прочитать память по этому адресу S0.x->x, то практически наверняка будет ошибка обращения к памяти и программа завершится.
А так бы она напечатала адрес, который хранится в этом указателе.
Например так:
Используется синтаксис C++
#include <iostream>

struct S {
    struct S* x;
} S0;

int main() {
    S0.x = &S0;
    std::cout << S0.x->x;
}
 

 Профиль  
                  
 
 Re: struct S* x;
Сообщение29.10.2021, 18:37 
Аватара пользователя


28/10/21
100
mihaild в сообщении #1536907 писал(а):
TheRuinedMap в сообщении #1536905 писал(а):
Потому что программа, вывод которой в текстовый поток не завершается переводом строки, вообще не обязана ничего никуда выводить
Почему? При уничтожении cout позовется flush.


А кто сказал, что будет иметь место какое-то аккуратное предсказуемое уничтожение? Поведение все равно не определено. На платформах, которые умеют формировать coredump, как правило в случае сегфолта вообще никакой "деструкции" не делается, то есть никакого "уничтожения cout" не будет иметь места.

Пробуем

Используется синтаксис C++
// test.cpp
#include <iostream>
#include <cstdlib>

int main(int argc, char* argv[])
{
   int d = 0;
   std::cout << "Hello World";
   return rand() / d;
}
 


Код:
[test] uname -a
Linux callisto 2.6.18-164.el5 #1 SMP Tue Aug 18 15:51:48 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
[test] g++ test.cpp
[test] ./a.out
Floating point exception
[test]


Как видите, ничего не выводится.

А если

Код:
[test] stdbuf -o0 ./a.out
Hello WorldFloating point exception
[test]


mihaild в сообщении #1536907 писал(а):
И причем тут перевод строки?


Стандарты языков С и С++ не оговаривают поведение текстовых потоков, если последняя строка текстового потока не заканчивается символом перевода строки.

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

 Профиль  
                  
 
 Re: struct S* x;
Сообщение29.10.2021, 19:05 
Заслуженный участник
Аватара пользователя


16/07/14
9202
Цюрих
TheRuinedMap в сообщении #1536910 писал(а):
А кто сказал, что будет иметь место какое-то аккуратное предсказуемое уничтожение?
Ну в вашем коде тоже UB, и в этом случае естественног ничего не гарантируется. Но мне показалось, что вы утверждаете, что любой код, выводящий строку без перевода, не обязан её выводить. Например
Используется синтаксис C++
#include <iostream> int main() { std::cout << "foobar"; return 0;}
- гарантируется ли по вашему мнению что строка выведется, или нет?
TheRuinedMap в сообщении #1536910 писал(а):
Стандарты языков С и С++ не оговаривают поведение текстовых потоков, если последняя строка текстового потока не заканчивается символом перевода строки
Можете процитировать? Я вижу что exit должно вызвать flush для всех буферизованных потоков (ну и при выходе из main зовется exit). Ничего релевантного про символ перевода строки (кроме существования line-buffered потоков) я не вижу.
TheRuinedMap в сообщении #1536910 писал(а):
А если ближе к реальной жизни: вывод в терминал обычно буферизуется построчно, из чего все и следует.
Из этого ничего не следует, что делает терминал (или как работает перенаправленный еще куда-то вывод) - это его личное дело, к стандарту и поведению программы отношения не имеющее.

 Профиль  
                  
 
 Re: struct S* x;
Сообщение29.10.2021, 19:21 
Аватара пользователя


28/10/21
100
mihaild в сообщении #1536913 писал(а):
TheRuinedMap в сообщении #1536910 писал(а):
А кто сказал, что будет иметь место какое-то аккуратное предсказуемое уничтожение?
Ну в вашем коде тоже UB, и в этом случае естественног ничего не гарантируется. Но мне показалось, что вы утверждаете, что любой код, выводящий строку без перевода, не обязан её выводить.


Нет, я такого не говорил. Я говорю лишь о том, что стандарт языка снимает с себя с ответственность за этот вопрос

http://port70.net/~nsz/c/c11/n1570.html#7.21.2p2
Цитата:
2 A text stream is an ordered sequence of characters composed into lines, each line consisting of zero or more characters plus a terminating new-line character. Whether the last line requires a terminating new-line character is implementation-defined [...].


И, так как в исходном вопросе не указана конкретная реализация, я, естественно, как и все присутствующие, испытал непреодолимое желание рассмотреть код с точки зрения голого стандарта языка.

mihaild в сообщении #1536913 писал(а):
Например
Используется синтаксис C++
#include <iostream> int main() { std::cout << "foobar"; return 0;}
- гарантируется ли по вашему мнению что строка выведется, или нет?


Нет, не гарантируется. Опять же, потому что вы задали вопрос про абстрактную С++ программу, без указания конкретной реализации. Это, однако, никак не мешает конкретным реализациям гарантировать вывод в таких случаях.

mihaild в сообщении #1536913 писал(а):
Можете процитировать? Я вижу что exit должно вызвать flush для всех буферизованных потоков (ну и при выходе из main зовется exit). Ничего релевантного про символ перевода строки (кроме существования line-buffered потоков) я не вижу.


В данном случае речь идет о самом определении "текстового потока": что является валидным текстовым потоком, а что нет.

TheRuinedMap в сообщении #1536910 писал(а):
Из этого ничего не следует, что делает терминал (или как работает перенаправленный еще куда-то вывод) - это его личное дело, к стандарту и поведению программы отношения не имеющее.


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

 Профиль  
                  
 
 Re: struct S* x;
Сообщение29.10.2021, 19:56 
Аватара пользователя


11/06/12
10390
стихия.вздох.мюсли
mihaild в сообщении #1536904 писал(а):
(кстати какой компилятор? у меня этот код ожидаемо сегфолтится)
У меня, например, тоже ничего не выводит (GCC 11.2.1).

 Профиль  
                  
 
 Re: struct S* x;
Сообщение29.10.2021, 20:11 
Заслуженный участник
Аватара пользователя


16/07/14
9202
Цюрих
Да, так лучше. Я почему-то не нашел это место (а в стандарте С++ кажется его вообще нет, ограничивается ссылкой на стандарт С)
Цитата:
A text stream is an ordered sequence of characters composed into lines, each line consisting of zero or more characters plus a terminating new-line character.
Вот это не очень понятно написано. Ниже написано
Цитата:
Output streams are flushed (any unwritten buffer contents are transmitted to the host environment) ...
и в описании exit
Цитата:
Next, all open streams with unwritten buffered data are flushed
Явно выписанного определения flushed я не нашел, и никакой связи с определением стрима я тут не вижу.
TheRuinedMap в сообщении #1536916 писал(а):
рассмотреть код с точки зрения голого стандарта языка
Естественно, что там напридумывали в реализациях неинтересно (и подозреваю что во всех встречающихся на практике реализациях программа при корректном завершении строку без перевода в конце выведет).
TheRuinedMap в сообщении #1536916 писал(а):
на практике именно эта буферизация как раз таки прекрасно управляется из программы через setvbuf
Но всё-таки по стандарту setvbuf управляет внутренней буфферизацией. Что дальше с выводом делает host - стандарт не говорит.
Aritaborian в сообщении #1536922 писал(а):
У меня, например, тоже ничего не выводит (GCC 11.2.1).
А это точно свойство компилятора (или скорее библиотеки), а не терминала? У меня в xterm выводится, компилятор gcc 11.1 (и с clang то же выводится), а код, если верить godbolt, одинаковый получается.

 Профиль  
                  
 
 Re: struct S* x;
Сообщение29.10.2021, 20:11 
Аватара пользователя


28/10/21
100
Aritaborian в сообщении #1536922 писал(а):
mihaild в сообщении #1536904 писал(а):
(кстати какой компилятор? у меня этот код ожидаемо сегфолтится)
У меня, например, тоже ничего не выводит (GCC 11.2.1).


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

Добавьте хотя бы std::cout << "Privet " << S0.x->x;. А без этого и говорить не о чем.

-- 29.10.2021, 09:14 --

mihaild в сообщении #1536925 писал(а):
У меня в xterm выводится, компилятор gcc 11.1 (и с clang то же выводится), а код, если верить godbolt, одинаковый получается.


Что выводится??? Как я понял Aritaborian ведет речь именно об исходном варианте от автора вопроса. Как там может что-то выводиться, если код сегфолтится?

 Профиль  
                  
 
 Re: struct S* x;
Сообщение29.10.2021, 20:17 
Аватара пользователя


11/06/12
10390
стихия.вздох.мюсли
Я догадался, что нужно добавить что-то выводимое на экран, и добавлял int a = 1; и std::cout << a;. Оно выводится.
Но! Догадался поменять местами две строки с cout и вот тут уже не выводится ничего. Но и предупреждений никаких нет тоже.

-- 29.10.2021, 20:18 --

mihaild в сообщении #1536925 писал(а):
А это точно свойство компилятора (или скорее библиотеки), а не терминала?
У меня PowerShell 7.1.5.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 53 ]  На страницу 1, 2, 3, 4  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group