Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607

Есть ли тут UB ?

09.03.2020, 12:27. Показов 3630. Ответов 55
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день, не могу разобрать вот такую ситуацию:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
 
using namespace std;
 
class A
{
public:
    A() { std::cout << "Adef" << std::endl; x = 4; }
    A(const A& _a) { std::cout << "cA&" << std::endl; x = 7; }
    unsigned x;
};
 
class B : public A
{
public:
    unsigned y;
    B()
    {std::cout << "Bdef" << std::endl; x = 3; y = 8; }
    B(const B& _b)
    { std::cout << "cB&" << std::endl; x = 7; }
    B& operator =(const B&)
    { std::cout << "B=&" << std::endl; x = 7; return *this; }
    int foo() const volatile { std::cout << "foo" << std::endl; return 555; }
};
 
int main()
{
    using std::cout;
    using std::endl;
    cout << "-----------" << endl;
    // class B : public A
    A * pa = new A; 
    A & ra = *pa;
    cout << "-----------" << endl;
    B & rb = static_cast<B&>(ra);
    rb.foo();
    rb.y = 55;
    cout << "-----------" << endl;
    return 0;
}
С одной стороны идёт обращение к полям и методам класса B, а с другой его конструктор нигде не вызывается.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
09.03.2020, 12:27
Ответы с готовыми решениями:

Есть ли тут такие, у кого есть свои идеи ,касающиеся компьютерной безопасности,например, по защите от вирусов?
Есть ли тут такие, у кого есть свои идеи ,касающиеся компьютерной безопасности,например, по защите от вирусов?

Есть ли тут утечка памяти?
Добрый вечер. Случайно возник такой вопрос: а вызывается ли деструктор для уже перемещенного объекта, если на его место перемещают другой? ...

И есть ли тут вообще список?
Есть программа. Скажите, какой это вид списка? И есть ли тут вообще список? struct car{ char name; // название марки машины int...

55
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13239 / 6871 / 1827
Регистрация: 18.10.2014
Сообщений: 17,417
10.03.2020, 19:04
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от IGPIGP Посмотреть сообщение
а потом допускается, что всё наоборот, то не шиза ли косит тех кто это пишет?
О чем речь? Где "допускается, что всё наоборот"?
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
10.03.2020, 19:14
Цитата Сообщение от DrOffset Посмотреть сообщение
Где допускается?
Вначале главы B - базовый (Base) а D - наследующий (Derived), а потом
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Если объект типа «cv1 B» на самом деле является подобъектом базового класса объекта типа D
тут я уже писал о двузначности. Кто тут базовый и кто наследник?
Если объект типа «cv1 B» на самом деле является подобъектом базового класса
это что значит? В это наследник или родитель?
По смыслу того, что объясняет Croessmah, - родитель, который содержится в объекте наследника. Но можно понять и что B - подобъект базового класса D. Черт-те что.
DrOffset, спасибо за объяснение.
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
10.03.2020, 19:23
Цитата Сообщение от IGPIGP Посмотреть сообщение
является подобъектом базового класса объекта типа D
можно понять и что B - подобъект базового класса D
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
10.03.2020, 19:30
Цитата Сообщение от IGPIGP Посмотреть сообщение
Кто тут базовый и кто наследник?
Все осталось как и было. Местами ничего не менялось.
Цитата Сообщение от IGPIGP Посмотреть сообщение
Если объект типа «cv1 B» на самом деле является подобъектом базового класса
это что значит?
If the object of type “cv1 B” is actually a base class subobject of an object of type D, the result refers to the enclosing object of type D.
Если объект B в самом деле является подобъектом [объектом базового класса] объекта класса D.
Может быть две ситуации.
*) Мы создали объект B (только объект B) и кастим ссылку на него к D. Это допускается синтаксисом и отношением между типами, потому что static_cast видит, что D наследник B - программа well-formed. Однако Мы не создавали D, у нас был только B. Получаем UB.
*) Мы создали объект D, ссылаемся на него через ссылку на B. Далее делаем static_cast к D. Это допустимо, потому что "B is actually a base class subobject of an object of type D".

Base class subobject объекта класса D - это объект типа B, B - это базовый класс, а подобъект он потому, что является частью "объемлющего" объекта D. Эта терминология в С++ изначально. Никто ее не трогал, не менял.

Добавлено через 1 минуту
Цитата Сообщение от IGPIGP Посмотреть сообщение
Но можно понять и что B - подобъект базового класса D. Черт-те что.
Я честно не понимаю как это можно так понять.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
10.03.2020, 19:44
Цитата Сообщение от DrOffset Посмотреть сообщение
Я честно не понимаю как это можно так понять.
If the object of type “cv1 B” is actually a base class subobject of an object of type D, the result refers to the enclosing object of type D.
Otherwise, the behavior is undefined.
Если объект квалиф B в действительности базового класса подобъект объекта типа D, результат ссылается на включающий объект типа D.
Я не смог прочесть, это именно так с первого раза. Именно этот момент я и просил объяснить.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13239 / 6871 / 1827
Регистрация: 18.10.2014
Сообщений: 17,417
10.03.2020, 20:57
Цитата Сообщение от IGPIGP Посмотреть сообщение
Если объект квалиф B в действительности базового класса подобъект объекта типа D, результат ссылается на включающий объект типа D.
Я не смог прочесть, это именно так с первого раза. Именно этот момент я и просил объяснить.
В языке С++ есть три типа подобъектов (subobjects):

1. Base class subobjects ("подобъекты базовых классов" или просто "базовые подобъекты")
2. Member subobjects ("подобъекты-члены", т.е. поля класса)
3. Элементы массива (по отношению к самому массиву)

Все эти три словосочетания обозначают вполне конкретные сущности и являются неделимыми.

Вы в своем предыдущем переводе перевели "base class subobject" как "подобъект базового класса", что вполне корректно. Но затем вы взяли и "распилили" это словосочетание пополам на две части: "подобъект" и "базового класса". И затем вы зачем-то решили, что вторая часть относится к D. То есть якобы D вдруг стал "базовым классом". Это неверный перевод. Все словосочетание "подобъект базового класса" является неделимым и целиком относитcя к B и только к B.

Процитированная вами фраза лучше переводится как

Если объект типа B в действительности является базовым подобъектом объекта типа D, то результат ссылается на его охватывающий объект (варианты: суперобъект, объект-владелец) типа D. В противном случае поведение не определено.
Никакой неоднозначности в этом тексте нет. Никакой инверсии ролей между B и D нет тоже.
2
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
11.03.2020, 00:44
Цитата Сообщение от DrOffset Посмотреть сообщение
Если объект B в самом деле является подобъектом [объектом базового класса] объекта класса D.
вот только static_cast работает в компалтайме.
и ему до лампочки dynamic-type объекта.

Цитата Сообщение от DrOffset Посмотреть сообщение
Получаем UB.
если статик_касту на вход подать фигню,
тогда на выходе так же закономерно получим фигню.

вот только поведение самого статик_ассерта при этом вполне себе определенное.
потому что оно независит от состояния объекта.

не?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13239 / 6871 / 1827
Регистрация: 18.10.2014
Сообщений: 17,417
11.03.2020, 01:18
Цитата Сообщение от hoggy Посмотреть сообщение
вот только static_cast работает в компалтайме.
Результат static_cast зависит от run-time значения аргумента. Поэтому ни о каком "static_cast работает в компалтайме" не может быть и речи. Более того, в "компалтайме" ничего никогда не работает. Даже понятия такого не существует. В компалтайме только генерируется код. А работать этот код может только в run-time.

Цитата Сообщение от hoggy Посмотреть сообщение
вот только поведение самого статик_ассерта при этом вполне себе определенное.
потому что оно независит от состояния объекта.
"статик_ассерта"?

Тут все очень просто:

Если стандарт языка говорит, что static_cast не "до лампочки" динамический тип объекта, значит static_cast не "до лампочки" динамический тип объекта. Если стандарт языка говорит, что данный static_cast порождает неопределенное поведение, значит данный static_cast порождает неопределенное поведение.

Все остальное - бессмысленные разглагольствования из серии "у Коляна Сиплого из третьего подъезда все работает".
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
11.03.2020, 07:52
Цитата Сообщение от hoggy Посмотреть сообщение
dynamic-type объекта
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
динамический тип объекта
Хватит теребить несуществующее понятие. Динамический тип это свойство выражения (http://eel.is/c++draft/defns.dynamic.type).
Лучше бы занялись вычищением неправильного использования терминологии в стандарте.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
11.03.2020, 11:42
UB и неопределённость результата. Для С++ это имхо не выгодная тема. Когда пытаются скрыть какашку говорят о фиче. Например о контекстной силе. Вот простое выражение:
C++
1
T *ptr_t(some_adress);
Можно ли быть уверенным в результате дальнейшего
C++
1
*ptr_t = some_val_t;
?
Никогда. some_adress может быть инициализирован нулём или не инициализирован вовсе. Кроме того, там может присутствовать неподходящий адрес. Так выходит это UB? А выход за границу массива (пресловутый), это UB? Там тоже по виду выражения нельзя сказать чем дело кончится. Именно действительные ран тайм значения определяют результат обращения по индексу.
Что касается интерпретации стандарта, то это дело неблагодарное, но без интерпретации знание становится религией. Особенно учитывая язык которым писан черновик. Именно поэтому разговоры программистов о стандарте так напоминают разговоры старшекласниц о любви и дружбе. И дело тут не в громкости и влажности. Слов и глаз конечно. А в яркости эмоций на фоне отстранённости от сути.
Я рискну предположить, что вопрос о преобразовании вниз от наследника к базовому связан исключительно с размещением. Тут, мне кажется, Croessmah, оказался близок к сути вопроса:
Цитата Сообщение от Croessmah Посмотреть сообщение
Там про указатели, но не суть,
Если я прав, то стандарт заложился на случай вроде:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
using namespace std;
struct B1
{
    int a1[10];
};
struct B2
{
    int a2[10];
};
 
struct D12 : public B1, public B2
{};
 
struct D21 : public B2, public B1
{};
 
struct D1 : public B1
{};
 
int main()
{
    D12 d12;
    B1 &b1_d12 = d12;
    B2 &b2_d12 = d12;
    cout<<"&b1_d12 vs &b2_d12 "<<&b1_d12<<' '<<&b2_d12<<endl;
 
    D21 d21;
    B1 &b1_d21 = d21;
    B2 &b2_d21 = d21;
    cout<<"&b1_d21 vs &b2_d21 "<<&b1_d21<<' '<<&b2_d21<<endl;
 
    //and
    D1 d1;
    B1 &b1=d1;
    cout<<"&b1 vs &d1 "<<&b1<<' '<<&d1<<endl;
 
return 0;
}
Но можно было бы и проще это объяснить. Что же касается возможности какой-то совсем нездоровой реализации одиночного наследования, в одной ступени, где размещение субобъекта суперкласса (люблю эту терминологию) по адресу не совпадает с enclosing суперобъектом субкласса, то это несколько свечемонахиньский маразм. Может я снова не прав?
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
11.03.2020, 12:21
IGPIGP, твоя писанина была бы отличным примером для учебника по психиатрии/психопатологии (раздел «расстройства/нарушения мышления», подраздел «резонёрство»).
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
11.03.2020, 13:14
Цитата Сообщение от argcargv Посмотреть сообщение
IGPIGP, твоя писанина была бы отличным примером для учебника по психиатрии/психопатологии (раздел «расстройства/нарушения мышления», подраздел «резонёрство»).
Я сразу признал в вас матёрого психиатра-психотерапевта. Это и есть причина по которой я вам практически не отвечаю. Однако ввиду последнего обострения просто вынужден. Напишите что-то по теме, если хотите.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13239 / 6871 / 1827
Регистрация: 18.10.2014
Сообщений: 17,417
11.03.2020, 20:38
Цитата Сообщение от IGPIGP Посмотреть сообщение
Я рискну предположить, что вопрос о преобразовании вниз от наследника к базовому связан исключительно с размещением. Тут, мне кажется, Croessmah, оказался близок к сути вопроса:
Вы даже не поняли, о чем речь.

Цитата Сообщение от IGPIGP Посмотреть сообщение
Что же касается возможности какой-то совсем нездоровой реализации одиночного наследования, в одной ступени, где размещение субобъекта суперкласса (люблю эту терминологию) по адресу не совпадает с enclosing суперобъектом субкласса, то это несколько свечемонахиньский маразм. Может я снова не прав?
Во-первых, нет никаких причин отделять одиночное наследование от множественного в С++. Никакой качественной разницы между ними нет. Совпадение адресов предков и потомков - это никого не интересующая мелочь, независимо от того, множественное ли наследование используется или одиночное.

Во-вторых, да, в обычных повседневных реализациях даже при одиночном наследовании адрес предка может не совпадать с адресом потомка. Например в ситуациях, когда предок не полиморфен, а потомок - полиморфен. Никакого "маразма" в этом нет: из практических соображений намного важнее и эффективнее обеспечить хранение указателя на VMT в самом начале объекта, чем обеспечивать никому не нужное совпадение адреса предка с адресом потомка.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
11.03.2020, 22:27
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Вы даже не поняли, о чем речь.
Вполне возможно. Я предложил версию и она имеет какую-то логику. Предложите свою.
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Совпадение адресов предков и потомков - это никого не интересующая мелочь
В чём же тогда трудность?
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Во-вторых, да, в обычных повседневных реализациях даже при одиночном наследовании адрес предка может не совпадать с адресом потомка.
А вот это, действительно, грустно. Интересно бы увидеть пример.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13239 / 6871 / 1827
Регистрация: 18.10.2014
Сообщений: 17,417
11.03.2020, 22:32
Цитата Сообщение от IGPIGP Посмотреть сообщение
В чём же тогда трудность?
Не понимаю, о чем речь. Какая трудность?

Цитата Сообщение от IGPIGP Посмотреть сообщение
А вот это, действительно, грустно. Интересно бы увидеть пример.
Грустно было бы, если бы было иначе.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
 
struct B
{
  int i;
};
 
struct D : B
{
  int j;
  virtual ~D() {}
};
 
int main()
{
  D d;
  std::cout << &d << " " << (B *) &d << std::endl;
}
GCC:
Code
1
0x7ffff3a44150 0x7ffff3a44158
Clang:
Code
1
0x7ffcf9798278 0x7ffcf9798280
MS Visual Studio:
Code
1
000000969059FA98 000000969059FAA0
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
11.03.2020, 22:34
Убедили)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
11.03.2020, 22:34

Есть ли тут ошибки? У меня С++ виснет и ничего не выдает
#include &quot;stdafx.h&quot; #include &lt;cstring&gt; #include &lt;iostream&gt; #include &lt;string&gt; #include &lt;cstdlib&gt; using namespace std; ...

Есть тут кто работает с++ + intel xeon phi 5110p ?
Добрый день, хотел бы пообщаться на эту тему, кто пишет на с++ уже софт и занимается отладной используя intel xeon phi 5110p.

Даны натуральные числа n, k. Проверить, есть ли в записи числа nk цифра m. тут число n в степени k, то есть k
Даны натуральные числа n, k. Проверить, есть ли в записи числа nk цифра m. Надо оформить данный код в HTML документ. var n =...

Тут есть профессионалы по JS
Ищу профессионала для создания очень простого скрипта,в JavaScript

Тут есть Ошибка?
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
56
Ответ Создать тему
Новые блоги и статьи
Книги по геймдизайну, левел-дизайну, игровым механикам и проектированию игрового опыта
8Observer8 08.11.2026
Содержание блога | English Version 1. 2003 - 06 - Designing Virtual Worlds (1st Edition) Автор: Richard A. Bartle | Объем: 768 стр. Ссылки: Amazon . . .
Родители токсичные абьюзеры по отношению к своим детям ругают их оскорбляют не любят
zorxor 08.11.2026
Жить в атмосфере постоянных оскорблений, критики и холодности со стороны родителей — это тяжелое и болезненное испытание, которое оставляет глубокие эмоциональные раны. Токсичное и абьюзивное. . .
Как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Ответ от Джемени ИИ.
zorxor 08.11.2026
Джемени, как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Многие люди, возвращаясь домой, сразу переодеваются в максимально свободную одежду или вовсе предпочитают. . .
Паттерн очереди действий/команд (Action / Command Queue). Система очереди действий и кат-сцен с SDL3 Callbacks, cglm и OpenGL
8Observer8 07.11.2026
Содержание блога | English Version Руководство для начинающих по реализации паттерна очереди действий/ команд (Action / Command Queue) на C++ (C++20) с использованием официального SDL3 Callbacks. . .
Проверка полного ФИО в типовом справочнике
Maks 07.11.2026
Решение реализовано в конфигурации КА2, на примере справочника "КонтактныеЛицаПартнеров". Задача: Запрет инициалов. Не допускаеть использование сокращений вида "И. И. ", "И. И. ", "И И" и. . .
Про "Windows must die!"
kumehtar 04.11.2026
Знаете, чет накатило. . . . Когда-то это было почти боевым кличем: мол, нормальный человек сидит на DOS, OS/ 2 или Linux, а вот это вот - Must Die. А теперь человек произносит «мастдай» с усмешкой - и. . .
Красочные поля с номером страницы svg+background-image
russiannick 04.11.2026
Красочные поля с номером страницы не менее важны чем в эпоху бумажных книг. Посему спешу представить почтеннейшей публике этот важный инструмент который эти поля и формирует. В процессе разработки. . .
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru