Корректен ли код
От: Евгений Коробко  
Дата: 11.08.04 11:02
Оценка:
class Vect
{
...
public:
double operator [] (int i) const {return *(&x+i);};
private:
double x,y,z;
};

Собственно, вопрос вызывает то, можно ли быть уверенным, что x,y,z будут расположены в памяти подряд?
Евгений Коробко
Re: Корректен ли код
От: achp  
Дата: 11.08.04 11:07
Оценка:
Здравствуйте, Евгений Коробко, Вы писали:

ЕК>Собственно, вопрос вызывает то, можно ли быть уверенным, что x,y,z будут расположены в памяти подряд?


Нет.
Re: Корректен ли код
От: Анатолий Широков СССР  
Дата: 11.08.04 11:08
Оценка:
ЕК>Собственно, вопрос вызывает то, можно ли быть уверенным, что x,y,z будут расположены в памяти подряд?

Нет, такой гарантии нет. Для гарантии необходимо использовать массив.
Re: Корректен ли код
От: dupamid Россия  
Дата: 11.08.04 11:12
Оценка:
Здравствуйте, Евгений Коробко, Вы писали:

ЕК>class Vect

ЕК>{
ЕК>...
ЕК>public:
ЕК> double operator [] (int i) const {return *(&x+i);};
ЕК>private:
ЕК> double x,y,z;
ЕК>};

ЕК>Собственно, вопрос вызывает то, можно ли быть уверенным, что x,y,z будут расположены в памяти подряд?


Так как пример написан — нет (есть private члены). Для того чтобы была гарантия последовательного размещения класс должен быть POD. На практике обычно будет работать.
Re[2]: Корректен ли код
От: Анатолий Широков СССР  
Дата: 11.08.04 11:14
Оценка:
D>Так как пример написан — нет (есть private члены). Для того чтобы была гарантия последовательного размещения класс должен быть POD.

Причем здесь POD?
Re: Корректен ли код
От: Glоbus Украина  
Дата: 11.08.04 11:14
Оценка:
Здравствуйте, Евгений Коробко, Вы писали:

ЕК>class Vect

ЕК>{
ЕК>...
ЕК>public:
ЕК> double operator [] (int i) const {return *(&x+i);};
ЕК>private:
ЕК> double x,y,z;
ЕК>};

ЕК>Собственно, вопрос вызывает то, можно ли быть уверенным, что x,y,z будут расположены в памяти подряд?


Нет
Удачи тебе, браток!
Re: Корректен ли код
От: Sergey Россия  
Дата: 11.08.04 11:18
Оценка:
Hello, Евгений!
You wrote on Wed, 11 Aug 2004 11:02:48 GMT:

ЕК> class Vect

ЕК> {
ЕК> ...
ЕК> public:
ЕК> double operator [] (int i) const {return *(&x+i);};
ЕК> private:
ЕК> double x,y,z;
ЕК> };

ЕК> Собственно, вопрос вызывает то, можно ли быть уверенным, что x,y,z

ЕК> будут расположены в памяти подряд?

Можно. Только между ними могут быть дырки для выравнивания. Пункт стандарта
9.2.12:
12 Nonstatic data members of a (nonunion) class declared without an
intervening accessspecifier

are allocated so that later members have higher addresses within a class
object. The order of allocation of nonstatic

data members separated by an accessspecifier is unspecified (11.1).
Implementation alignment requirements

might cause two adjacent members not to be allocated immediately after each
other; so might

requirements for space for managing virtual functions (10.3) and virtual
base classes (10.1).


With best regards, Sergey.
Posted via RSDN NNTP Server 1.9 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[3]: Корректен ли код
От: dupamid Россия  
Дата: 11.08.04 11:23
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

D>>Так как пример написан — нет (есть private члены). Для того чтобы была гарантия последовательного размещения класс должен быть POD.


АШ>Причем здесь POD?


Так как для POD есть требование совместимости по раскладке (layout-compatible), то для POD-struct члены должны лежать последовательно. Если говорить упрощенно то две структуры с одинаковым началом должны содержать одинаковые члены на одинаковых местах. Так что можно построить последовательность структур, в каждой на один член больше чем в предыдущей и их начала должны быть разложены одинаково, для того чтобы это соблюсти придется разложить члены последовательно.
Re[2]: Корректен ли код
От: Евгений Коробко  
Дата: 11.08.04 11:24
Оценка:
Спасибо!
Реально дырок для выравнивания, вероятно, не будет, потому как для double вряд ли будет выравнивание по 16 байт. В крайнем случае, можно управлять выравниваем директивами компиляторы
Евгений Коробко
Re[2]: Корректен ли код
От: Евгений Коробко  
Дата: 11.08.04 11:26
Оценка:
Такой код не работает:
class Vect
{
...
private:
double items[3];
double& x=items[0];
double& y=items[1];
double& z=items[2];
};

А через индексы уж больно некрасиво выглядит.
Евгений Коробко
Re[3]: Корректен ли код
От: maq Россия http://www.maqdev.com
Дата: 11.08.04 11:32
Оценка:
Здравствуйте, Евгений Коробко, Вы писали:

ЕК>Такой код не работает:

ЕК>class Vect
ЕК>{
ЕК>...
ЕК>private:
ЕК> double items[3];
ЕК> double& x=items[0];
ЕК> double& y=items[1]; 
ЕК> double& z=items[2];
ЕК>};

Все верно — инициализация ссылок должна быть в конструкторе.
Еще можно предложить такой вариант:
    class Vect
    {
            ...
    private:
        double items[3];
        enum {x,y,z};
        ...
        // юзаем как items[x], items[y] ...
    };


ЕК>А через индексы уж больно некрасиво выглядит.
... << RSDN@Home 1.1.4 beta 2 >>
Re[4]: Корректен ли код
От: achp  
Дата: 11.08.04 11:32
Оценка:
Здравствуйте, dupamid, Вы писали:

D>Так как для POD есть требование совместимости по раскладке (layout-compatible), то для POD-struct члены должны лежать последовательно.


По возрастанию адресов — да, но вряд ли последовательно.
Re: Корректен ли код
От: ssm Россия  
Дата: 11.08.04 11:33
Оценка:
Здравствуйте, Евгений Коробко, Вы писали:



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


class Vect
{
public:
  double operator [] (int i) const {return arr[i];}
private:
  double arr[3];
  double &x(){return arr[0];}
  double &y(){return arr[1];}
  double &z(){return arr[2];}
};
Re[3]: Корректен ли код
От: rus blood Россия  
Дата: 11.08.04 11:33
Оценка:
Здравствуйте, Евгений Коробко, Вы писали:

ЕК>Такой код не работает:

ЕК>class Vect
ЕК>{
ЕК>...
ЕК>private:
ЕК> double items[3];
ЕК> double& x=items[0];
ЕК> double& y=items[1];
ЕК> double& z=items[2];
ЕК>};


class Vect
{
public:
    Vect() : x(items[0]), y(items[1]), z(items[2]) {}

private:
    double items[3];
    double& x;
    double& y;
    double& z;
};
Имею скафандр — готов путешествовать!
Re[2]: Корректен ли код
От: Bell Россия  
Дата: 11.08.04 11:39
Оценка:
Здравствуйте, dupamid, Вы писали:


D>Так как пример написан — нет (есть private члены). Для того чтобы была гарантия последовательного размещения класс должен быть POD. На практике обычно будет работать.


А что насчет выравнивания?
Любите книгу — источник знаний (с) М.Горький
Re[4]: Корректен ли код
От: Анатолий Широков СССР  
Дата: 11.08.04 11:39
Оценка:
RB>
RB>class Vect
RB>{
RB>public:
RB>    Vect() : x(items[0]), y(items[1]), z(items[2]) {}

RB>private:
RB>    double items[3];
RB>    double& x;
RB>    double& y;
RB>    double& z;
RB>};
RB>



Провал:

const Vect v;

v.x = 10;
v.y = 20;
v.y = 30;


Надо дополнительно шаблон reference дописать, чтобы член данных вел себя как подобает.
Re: Корректен ли код
От: ilnar Россия  
Дата: 11.08.04 11:40
Оценка:
Здравствуйте, Евгений Коробко, Вы писали:

ЕК>class Vect

ЕК>{
ЕК>...
ЕК>public:
ЕК> double operator [] (int i) const {return *(&x+i);};
ЕК>private:
ЕК> double x,y,z;
ЕК>};

ЕК>Собственно, вопрос вызывает то, можно ли быть уверенным, что x,y,z будут расположены в памяти подряд?


да
Re[2]: Корректен ли код
От: Кирпа В.А. Украина  
Дата: 11.08.04 11:41
Оценка: :)
Здравствуйте, ssm, Вы писали:

ssm>Здравствуйте, Евгений Коробко, Вы писали:




ssm>раньше я так делал очень часто, но видимо могут возникнуть проблемы с выравниванием, может так получше будет?



ssm>
ssm>class Vect
ssm>{
ssm>public:
ssm>  double operator [] (int i) const { ASSERT(i >= 0 && i < 3);  return arr[i];}
ssm>private:
ssm>  double arr[3];
ssm>  double &x(){return arr[0];}
ssm>  double &y(){return arr[1];}
ssm>  double &z(){return arr[2];}
ssm>};
ssm>



маленький штришок
!0xDEAD
Re[5]: Корректен ли код
От: dupamid Россия  
Дата: 11.08.04 11:45
Оценка:
Здравствуйте, achp, Вы писали:

D>>Так как для POD есть требование совместимости по раскладке (layout-compatible), то для POD-struct члены должны лежать последовательно.


A>По возрастанию адресов — да, но вряд ли последовательно.


Последовательно, но с точностью до выравнивания. Так как у POD не может быть срытых полей, кроме как для вырвнивания. Пример:
struct A1
{
  int a1;
};

struct A2
{
  int a1;
  float a2;
};

struct A3
{
  int a1;
  float a2;
  double a3;
};

и т.д.

Так вот так как начала стуруктур должны быть совместимы, то получается что члены должны лежать последоватлеьно. Например, если указатьль на A3 преобразовать в указатель на A2, то доступ к полям должен осуществляться без проблем. Такие требования есть наследие С. Где было популярно в следующей версии добавлять поля в структуры, при этом раскладка ее начала должна быть одинаковой для бинарной совместимости со старыми программами.
Re[3]: Корректен ли код
От: dupamid Россия  
Дата: 11.08.04 11:49
Оценка:
Здравствуйте, Bell, Вы писали:

D>>Так как пример написан — нет (есть private члены). Для того чтобы была гарантия последовательного размещения класс должен быть POD. На практике обычно будет работать.


B>А что насчет выравнивания?


В данном случае это не проблема, так как все члены одного типа. Вот если они будут разных типов, пусть даже одного размера — тогда могут быть проблемы.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.