Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Специальные поля в заголовках структур и классов, - в каких случаях появляются 
V
    Опции темы
marcusmae
Дата 18.8.2008, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 5
Всего: 39



Здравствуйте,

В каких случаях в заголовке структур и классов перед данными располагаются специальные поля типа указателя на таблицу виртуальных функций? Интересует вообще всё, что может находиться между адресом экземпляра и адресом верхнего поля. Если случаев немного, то перечислите, пожалуйста, кратко и / если нет подскажите, где почитать. Кстати, стандарт на этот счёт что-то определяет?..

Спасибо.


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
bsa
Дата 18.8.2008, 14:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Думаю, что если это и есть, то компиляторозависимо.
PM   Вверх
Alek86
Дата 18.8.2008, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



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


--------------------
user posted image    user posted image
PM MAIL   Вверх
marcusmae
Дата 18.8.2008, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 5
Всего: 39



Цитата(Alek86 @  18.8.2008,  14:51 Найти цитируемый пост)
стандарт говорит, что это не определенои размер класса и расположение данных внутри него - на совести компилятора


если под рукой, можно цитату?..


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
UnrealMan
Дата 18.8.2008, 15:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(marcusmae @  18.8.2008,  16:10 Найти цитируемый пост)
если под рукой, можно цитату?.. 

Правильно сделал, что спросил: тебе нагло наврали (тут такое нередко бывает smile)

Цитата(9.2 Class members)
Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated
so that later members have higher addresses within a class object. The order of allocation of nonstatic
data members separated by an access-specifier is unspecified (11.1).

Цитата(9.2 Class members)
A pointer to a POD-struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa. [Note: There might therefore be unnamed padding within a POD-struct object, but not at its beginning, as necessary to achieve appropriate alignment. ]


Это сообщение отредактировал(а) UnrealMan - 18.8.2008, 15:57
PM MAIL   Вверх
Daevaorn
Дата 18.8.2008, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



И где наврали?
PM MAIL WWW   Вверх
SABROG
Дата 18.8.2008, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Такую фигню накатал.

Код

#include <iostream>
using namespace std;

class test
{
public:
    test()
    {
        data = -1;
        data = 1;
        data2 = 2;
    };
    ~test(){};
    int data;
    int data2;
    unsigned char data3;
};
class test2
{
public:
    test2()
    {
        data = -1;
        data = 1;
        data2 = 2;
    };
    ~test2(){};
    int data;
    int data2;
    unsigned char data3;
};

int main(int argc, char *argv[])
{
    test *pt = new test;
    test2 *pt2 = new test2;
    test pt3;
    test2 pt4; 
    cout << "main addr: " << (int *)&main << endl;
    cout << "base addr test: " << pt << "\ndata addr: " << (int *)&pt->data << "\ndata2 addr: " << (int *)&pt->data2 << "\ndata3 addr: " << (int *)&pt->data3 << endl;
    cout << "base addr test2: " << pt2 << "\ndata addr: " << (int *)&pt2->data << "\ndata2 addr: " << (int *)&pt2->data2 << "\ndata3 addr: " << (int *)&pt2->data3 << endl;
    cout << "base addr local test2: " << (int *)&pt4 << "\ndata addr: " << (int *)&pt4.data << "\ndata2 addr: " << (int *)&pt4.data2 << "\ndata3 addr: " << (int *)&pt4.data3 << endl;
    cout << "base addr local test: " << (int *)&pt3 << "\ndata addr: " << (int *)&pt3.data << "\ndata2 addr: " << (int *)&pt3.data2 << "\ndata3 addr: " << (int *)&pt3.data3 << endl;
    delete pt, pt2;
    return 0;
}


Выдало:

Код

main addr: 0x4012f0
base addr test: 0x3f2450
data addr: 0x3f2450
data2 addr: 0x3f2454
data3 addr: 0x3f2458
base addr test2: 0x3f24c8
data addr: 0x3f24c8
data2 addr: 0x3f24cc
data3 addr: 0x3f24d0
base addr local test2: 0x22ff40
data addr: 0x22ff40
data2 addr: 0x22ff44
data3 addr: 0x22ff48
base addr local test: 0x22ff50
data addr: 0x22ff50
data2 addr: 0x22ff54
data3 addr: 0x22ff58


Т.е. 112 байт затерялось где-то между классами при выделении памяти через new, а в стеке все идет по-порядку. Компилятор gcc, спец. заголовков перед данными не видать. Т.е. пока адрес класса равен адресу первого члена данных.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
marcusmae
Дата 18.8.2008, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 5
Всего: 39



UnrealMan, спасибо,

Цитата

Нестатические поля-значения не-union классов (т.е. структур и классов, да?) объявленные без intervening access-specifier размещаются в памяти таким образом, что чем ниже поле, тем выше его адрес в памяти. Порядок размещения нестатических полей-значений, разделённых intervening access-specifier неопределён. 


- что означает термин intervening access-specifier? Обычные спецификаторы доступа - private-public-protected, да? Если перевести на доступный язык, то получается, что в рамках секции с некоторым доступом все поля-значения размещаются ровно в том порядке, в каком они перечисленны в классе. Очень мило, что поля-указатели не оговариваются smile и что секции в принципе могут перемешиваться.

Второй тезис вообще пока не могу воткнуть smile 

SABROG, спасибо,

Будет гораздо интереснее, если Вы продолжите анализ, введя виртуальные функции и/или множественное наследование.


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
UnrealMan
Дата 18.8.2008, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(marcusmae @  18.8.2008,  17:18 Найти цитируемый пост)
Обычные спецификаторы доступа - private-public-protected, да? 

Да.

Цитата
access-specifier:
    private
    protected
    public


Цитата(marcusmae @  18.8.2008,  17:18 Найти цитируемый пост)
Если перевести на доступный язык, то получается, что в рамках секции с некоторым доступом все поля-значения размещаются ровно в том порядке, в каком они перечисленны в классе. 

Если между двумя нестатическими членами-данными не находится access-specifier, то больший адрес имеет тот, что объявлен позже. При этом между членами могут быть пустоты.

Касаемо POD-структур гарантируется, что объект такой структуры и его первый нестатический член-данное могут быть преобразованы друг в друга посредством reinterpret_cast:

Код

#include <iostream>

struct A
{
    double d;
    int i;
};

int main()
{
    A a;
    double &d = reinterpret_cast<double &>(a);
    d = 3.14;                                   // эквивалентно a.d = 3.14
    reinterpret_cast<A &>(d).i = 12;            // эквивалентно a.i = 12
    std::cout << a.d << " " << a.i << std::endl;
}


Это сообщение отредактировал(а) UnrealMan - 18.8.2008, 16:49
PM MAIL   Вверх
Alek86
Дата 18.8.2008, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(UnrealMan @  18.8.2008,  15:56 Найти цитируемый пост)
Правильно сделал, что спросил: тебе нагло наврали (тут такое нередко бывает )

а теперь покажи, где я наврал

я ответил, на вопрос
Цитата(marcusmae @  18.8.2008,  13:42 Найти цитируемый пост)
В каких случаях в заголовке структур и классов перед данными располагаются специальные поля типа указателя на таблицу виртуальных функций? Интересует вообще всё, что может находиться между адресом экземпляра и адресом верхнего поля.

ответ - не определено


--------------------
user posted image    user posted image
PM MAIL   Вверх
marcusmae
Дата 18.8.2008, 17:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 5
Всего: 39



Цитата(UnrealMan @  18.8.2008,  16:39 Найти цитируемый пост)
Если между двумя нестатическими членами-данными не находится access-specifier, то больший адрес имеет тот, что объявлен позже. При этом между членами могут быть пустоты.


Ну да. Именно это я и наблюдаю чаще всего.

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

Цитата(UnrealMan @  18.8.2008,  16:39 Найти цитируемый пост)

Код

double &d = reinterpret_cast<double &>(a);
d = 3.14;                                   // эквивалентно a.d = 3.14



- круто! А для reinterpret_cast нужен rtti?


Это сообщение отредактировал(а) marcusmae - 18.8.2008, 17:05


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
Alek86
Дата 18.8.2008, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(marcusmae @  18.8.2008,  17:04 Найти цитируемый пост)
из цитаты следует, что порядок следования членов определён в некоторой степени.

а, точно, я и про порядок говорил
не знал... smile


Цитата(marcusmae @  18.8.2008,  17:04 Найти цитируемый пост)
можно ли говорить хотя бы о каких-то закономерностях?

имхо, лучше на этот счет вообще не париться.
делать сериализацию и не морочить себе голову smile


--------------------
user posted image    user posted image
PM MAIL   Вверх
UnrealMan
Дата 18.8.2008, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(Alek86 @ 18.8.2008,  17:55)
Цитата(UnrealMan @  18.8.2008,  15:56 Найти цитируемый пост)
Правильно сделал, что спросил: тебе нагло наврали (тут такое нередко бывает )

а теперь покажи, где я наврал

я ответил, на вопрос
Цитата(marcusmae @  18.8.2008,  13:42 Найти цитируемый пост)
В каких случаях в заголовке структур и классов перед данными располагаются специальные поля типа указателя на таблицу виртуальных функций? Интересует вообще всё, что может находиться между адресом экземпляра и адресом верхнего поля.

ответ - не определено

Для POD-структуры гарантируется, что перед первым нестатическим членом-данным не может быть никаких неименованных пустот (см. примечание во второй приведённой мной цитате из п. 9.2 стандарта), а также что адрес её первого нестатического члена-данного совпадает с адресом её экземпляра (следствие из двух приведённый мной цитат). Это, по-твоему, можно расценивать как полное отсутвие в стандарте информации по данному топику? smile

Добавлено через 31 секунду
Цитата(marcusmae @  18.8.2008,  18:04 Найти цитируемый пост)
А для reinterpret_cast нужен rtti?

Нет.
PM MAIL   Вверх
bsa
Дата 18.8.2008, 20:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



блин. а я грешным делом подумал, что речь идет о чем-то, что находится до адреса, на который указывает указатель  smile 
PM   Вверх
Alek86
Дата 18.8.2008, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(UnrealMan @  18.8.2008,  18:47 Найти цитируемый пост)
Для POD-структуры гарантируется, что перед первым нестатическим членом-данным не может быть никаких неименованных пустот (см. примечание во второй приведённой мной цитате из п. 9.2 стандарта), а также что адрес её первого нестатического члена-данного совпадает с адресом её экземпляра (следствие из двух приведённый мной цитат). Это, по-твоему, можно расценивать как полное отсутвие в стандарте информации по данному топику?

стандарт на работе - завтра погляжу
а из 2х цитат сейчас следует только то, что reinterpret_cast обязан приводить указатель на ПОД к указателю на первое поле...

если в примечании написано то, чтоговоришь, тогда я был неправ


--------------------
user posted image    user posted image
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0596 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.