13 / 13 / 1
Регистрация: 19.10.2019
Сообщений: 607
1

Есть ли тут UB ?

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

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

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
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.03.2020, 12:27
Ответы с готовыми решениями:

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

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

И есть ли тут вообще список?
Есть программа. Скажите, какой это вид списка? И есть ли тут вообще список? struct car{ char...

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

55
Вездепух
Эксперт CЭксперт С++
11688 / 6367 / 1723
Регистрация: 18.10.2014
Сообщений: 16,050
10.03.2020, 19:04 41
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от IGPIGP Посмотреть сообщение
а потом допускается, что всё наоборот, то не шиза ли косит тех кто это пишет?
О чем речь? Где "допускается, что всё наоборот"?
0
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
10.03.2020, 19:14 42
Цитата Сообщение от 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 43
Цитата Сообщение от IGPIGP Посмотреть сообщение
является подобъектом базового класса объекта типа D
можно понять и что B - подобъект базового класса D
0
18822 / 9826 / 2401
Регистрация: 30.01.2014
Сообщений: 17,260
10.03.2020, 19:30 44
Цитата Сообщение от 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
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
10.03.2020, 19:44 45
Цитата Сообщение от 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Эксперт С++
11688 / 6367 / 1723
Регистрация: 18.10.2014
Сообщений: 16,050
10.03.2020, 20:57 46
Цитата Сообщение от 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
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
11.03.2020, 00:44 47
Цитата Сообщение от DrOffset Посмотреть сообщение
Если объект B в самом деле является подобъектом [объектом базового класса] объекта класса D.
вот только static_cast работает в компалтайме.
и ему до лампочки dynamic-type объекта.

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

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

не?
0
Вездепух
Эксперт CЭксперт С++
11688 / 6367 / 1723
Регистрация: 18.10.2014
Сообщений: 16,050
11.03.2020, 01:18 48
Цитата Сообщение от 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 49
Цитата Сообщение от hoggy Посмотреть сообщение
dynamic-type объекта
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
динамический тип объекта
Хватит теребить несуществующее понятие. Динамический тип это свойство выражения (http://eel.is/c++draft/defns.dynamic.type).
Лучше бы занялись вычищением неправильного использования терминологии в стандарте.
0
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
11.03.2020, 11:42 50
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 51
IGPIGP, твоя писанина была бы отличным примером для учебника по психиатрии/психопатологии (раздел «расстройства/нарушения мышления», подраздел «резонёрство»).
0
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
11.03.2020, 13:14 52
Цитата Сообщение от argcargv Посмотреть сообщение
IGPIGP, твоя писанина была бы отличным примером для учебника по психиатрии/психопатологии (раздел «расстройства/нарушения мышления», подраздел «резонёрство»).
Я сразу признал в вас матёрого психиатра-психотерапевта. Это и есть причина по которой я вам практически не отвечаю. Однако ввиду последнего обострения просто вынужден. Напишите что-то по теме, если хотите.
0
Вездепух
Эксперт CЭксперт С++
11688 / 6367 / 1723
Регистрация: 18.10.2014
Сообщений: 16,050
11.03.2020, 20:38 53
Цитата Сообщение от IGPIGP Посмотреть сообщение
Я рискну предположить, что вопрос о преобразовании вниз от наследника к базовому связан исключительно с размещением. Тут, мне кажется, Croessmah, оказался близок к сути вопроса:
Вы даже не поняли, о чем речь.

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

Во-вторых, да, в обычных повседневных реализациях даже при одиночном наследовании адрес предка может не совпадать с адресом потомка. Например в ситуациях, когда предок не полиморфен, а потомок - полиморфен. Никакого "маразма" в этом нет: из практических соображений намного важнее и эффективнее обеспечить хранение указателя на VMT в самом начале объекта, чем обеспечивать никому не нужное совпадение адреса предка с адресом потомка.
0
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
11.03.2020, 22:27 54
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Вы даже не поняли, о чем речь.
Вполне возможно. Я предложил версию и она имеет какую-то логику. Предложите свою.
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Совпадение адресов предков и потомков - это никого не интересующая мелочь
В чём же тогда трудность?
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Во-вторых, да, в обычных повседневных реализациях даже при одиночном наследовании адрес предка может не совпадать с адресом потомка.
А вот это, действительно, грустно. Интересно бы увидеть пример.
0
Вездепух
Эксперт CЭксперт С++
11688 / 6367 / 1723
Регистрация: 18.10.2014
Сообщений: 16,050
11.03.2020, 22:32 55
Цитата Сообщение от 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:
Код
0x7ffff3a44150 0x7ffff3a44158
Clang:
Код
0x7ffcf9798278 0x7ffcf9798280
MS Visual Studio:
Код
000000969059FA98 000000969059FAA0
1
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
11.03.2020, 22:34 56
Убедили)
0
11.03.2020, 22:34
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.03.2020, 22:34
Помогаю со студенческими работами здесь

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
56
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru