АШ>не может сделать что-то подобное:
АШ>| x |XXXX| y |XXXX| z |XXXX
АШ>Именно в этом состоял первоначалный вопрос. И компилятор волен вполне так поступить, поскольку стандарт ему это не запрещает. Поэтому код
АШ>является хаком в том, смысле, что безосновательно полагается на то, что между x, y и z нет "дыр".
Вмешаюсь в беседу, извините. Почему-то все говорят про Стандарт, забывая о том, что это лишь один из документов, регулирующих поведение компилятора. Когда мы говорим о C-структурах, т.е. о типах, поля которых используются напрямую, то большее значение имеет другой документ: ABI (Application Binary Interface) спецификация. Именно она регулирует подобные вещи в большей степени, стремясь к гарантии, что вы можете использовать библиотеки и заголовочные файлы, полученные с помощью другого компилятора.
В частности, именно Intel 386 ABI запрещает компилятору сделать "что-то подобное", приведенное выше, поскольку
1. An entire structure or union object is aligned on the same boundary as its
most strictly aligned member.
2. Each member is assigned to the lowest available offset with the appropriate
alignment. This may require internal padding, depending on the previous
member.
Т.е. начало структуры обязано быть выравнено на границу выравнивания для double. Первый элемент double должен начинаться с минимально подходящего для него адреса, т.е. сразу. Второй элемент — то же самое, т.е. немедленно после первого элемента.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
It's kind of fun to do the impossible (Walt Disney)
Здравствуйте, srggal, Вы писали:
S>Здравствуйте, Alex Alexandrov, Вы писали:
AA>>Разработчики ПО обязаны знать об ABI. Когда ты пишешь библиотеку под Unix, тебе надо понимать это хотя бы для того, чтобы понять, является ли новая версия твоей библиотеки ABI-совместимой с предыдущей, и какую цифру в версии таки надо менять (major/minor/patch). Когда начинаются глюки с С++ рантаймом также надо знать, что такое ABI и когда у GCC он поменялся. И т.д.
S>Насколько сильно я ошибусь предположив что руководствуясь стандартом языка С/С++ я могу абстрагироваться от АБИ?
S>Если Вас не затруднит — приведите пример когда с точки зрения стандарта код будет well-formed, но при этом Он не будет удовлетворять AАБИ.
S>Стандарт ИМХО для того и писан, чтобы абстрагироваться от платформы
Да легко: собери одну часть своего well-formed кода одинм компилятором, а другую — другим, а потом попробуй их заставить работать вместе.
Причем это имеет место даже для одного и того же компилятора, но разных его версий, или разных ключей компиляции.
Например, Sun поменял ABI своего компилятора при переходе с версии 4.2 на 5.x.
Для нашей системы это означало то, что теперь мы должны достать новые версии всех сторонних библиотек, собранные пятеркой.
Некоторые библиотеки их получить не удалось (по разным причинам — в одном случае фирма просто перестала существовать, в другом — запросила дополнительное бабло, в третьем — вообще переписала библиотеку на java и них теперь вообще нет интерфейса для С++), и в результате у нас один и тот же код компилируется дважды разными компиляторами — для сборки со старыми библиотеками и для сборки с новыми.
И из-за недоступности версий старых библиотек, поддерживающих ABI нового компилятора, у нас нет никакой надежды перевести приложения, которые с этими библиотеками линкуются, на нормальный С++ от версии 5.x.
Здравствуйте, Alex Alexandrov, Вы писали:
AA>Разработчики ПО обязаны знать об ABI. Когда ты пишешь библиотеку под Unix, тебе надо понимать это хотя бы для того, чтобы понять, является ли новая версия твоей библиотеки ABI-совместимой с предыдущей, и какую цифру в версии таки надо менять (major/minor/patch). Когда начинаются глюки с С++ рантаймом также надо знать, что такое ABI и когда у GCC он поменялся. И т.д.
Насколько сильно я ошибусь предположив что руководствуясь стандартом языка С/С++ я могу абстрагироваться от АБИ?
Если Вас не затруднит — приведите пример когда с точки зрения стандарта код будет well-formed, но при этом Он не будет удовлетворять AАБИ.
Стандарт ИМХО для того и писан, чтобы абстрагироваться от платформы
Hello, dupamid!
You wrote on Wed, 11 Aug 2004 13:29:28 GMT:
d> Использовать это для оптимизации выравнивания нельзя, так как размер d> типа в массиве и самомого по себе должен быть одинаковым. Т.е. d> реализация, на которой sizeof типа long double 10 байт, а в масиве их d> кладут через 16 — для выравнивания, не соответсвует Стнадарту. Теперь, d> если вернуться у структурам, то получается что sizeof типов уже и так d> выровнены для нормального последовательного размещения, так что d> вставлять дыры смысла не имеет никакого.
Не так. Есть у нас10-байтный long double, в массив его приходится класть
подряд — чтоб по стандарту, а в структуру имеем право класть с дырками — и
так и делаем, для оптимизации. Где противоречие?
With best regards, Sergey.
Posted via RSDN NNTP Server 1.9 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
С другой стороны, выпендреж все это — неоправданный расход sizeof(reference_member<double>)*3 + const байт памяти ради сомнительно "высокого" искусства. Поэтому надо оставить:
Здравствуйте, Sergey, Вы писали:
d>> Можещь посмотреть на gcc под Windows — 12, на Intel C++ (/Qlong_double) — 16.
S>И что с того? Под Win 16 у кучи компиляторов long double 80-bit был.
Так и у Win32 это все тот же 80-битный long double (в этом смысле размеры типов у FPU не изменились), его размер увеличен для выравнивания.
Здравствуйте, Евгений Коробко, Вы писали:
ЕК>Собственно, вопрос вызывает то, можно ли быть уверенным, что x,y,z будут расположены в памяти подряд?
Конечно нельзя, но, как мне кажется, если очень нужно, то можно. Особенно для POD. (При этом можно хакнуть хитро -- завести структуру, где только поля, а уж её сделать полем этого хитрого класса)
Я прочитал всю ветку, и удивился, что никто не предложил пользоваться таким "почти стандартным" поведением, но при этом проверять его CT-assert'ом, например C_ASSERT
В конце концов это довольно надёжно. Если кто-то будет переносить этот код на какую-то дргугую платформу, где таки хак не работает, то там можно это дело подправить, например при помощи прагм.
Кроме того, я хочу немного уточнить ситуацию с бинарной совместимостью.
Конечно реализаций C++ очень много, среди них есть очень причудливые.
Но при этом, платформ на свете гараздо меньше. И на каждой есть API. Так что по крайней мере надо быть совместиммы с ним по раскладке структур.
Я не знаю платформ, где описываемое поведение нарушалось бы. Так что у компилятора, который хочет быть "не как все" есть два пути.
1) Быть не как все на каких-то экзотических типах, которых нет в API, например на long double, который больше 8 байт.
2) Иметь какие-то прагмы, которые для некоторых структур это "особое" поведение выключают.
Так что мне кажется, что такой подход вполне можно использовать, но только в случае, если есть веские основания (они, кстати, могут оказаться ещё более неперносимыми)
Правда если доступ к полям завернуть в методы, то на проблемной платформе всегда будет маза перейти к решению с методами возвращающими ссылки на элементы массива
Ну а резон, описанный в этом топике мне кажется не таким уж и весомым
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Евгений Коробко, Вы писали:
ЕК>class Vect ЕК>{ ЕК>... ЕК>public: ЕК> double operator [] (int i) const {return *(&x+i);}; ЕК>private: ЕК> double x,y,z; ЕК>};
ЕК>Собственно, вопрос вызывает то, можно ли быть уверенным, что x,y,z будут расположены в памяти подряд?
Так как пример написан — нет (есть private члены). Для того чтобы была гарантия последовательного размещения класс должен быть POD. На практике обычно будет работать.
Здравствуйте, Евгений Коробко, Вы писали:
ЕК>class Vect ЕК>{ ЕК>... ЕК>public: ЕК> double operator [] (int i) const {return *(&x+i);}; ЕК>private: ЕК> double x,y,z; ЕК>};
ЕК>Собственно, вопрос вызывает то, можно ли быть уверенным, что x,y,z будут расположены в памяти подряд?
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 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Анатолий Широков, Вы писали:
D>>Так как пример написан — нет (есть private члены). Для того чтобы была гарантия последовательного размещения класс должен быть POD.
АШ>Причем здесь POD?
Так как для POD есть требование совместимости по раскладке (layout-compatible), то для POD-struct члены должны лежать последовательно. Если говорить упрощенно то две структуры с одинаковым началом должны содержать одинаковые члены на одинаковых местах. Так что можно построить последовательность структур, в каждой на один член больше чем в предыдущей и их начала должны быть разложены одинаково, для того чтобы это соблюсти придется разложить члены последовательно.
Спасибо!
Реально дырок для выравнивания, вероятно, не будет, потому как для double вряд ли будет выравнивание по 16 байт. В крайнем случае, можно управлять выравниваем директивами компиляторы
Здравствуйте, dupamid, Вы писали:
D>Так как для POD есть требование совместимости по раскладке (layout-compatible), то для POD-struct члены должны лежать последовательно.
По возрастанию адресов — да, но вряд ли последовательно.
D>Так как пример написан — нет (есть private члены). Для того чтобы была гарантия последовательного размещения класс должен быть POD. На практике обычно будет работать.
Здравствуйте, Евгений Коробко, Вы писали:
ЕК>class Vect ЕК>{ ЕК>... ЕК>public: ЕК> double operator [] (int i) const {return *(&x+i);}; ЕК>private: ЕК> double x,y,z; ЕК>};
ЕК>Собственно, вопрос вызывает то, можно ли быть уверенным, что x,y,z будут расположены в памяти подряд?
Здравствуйте, 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, то доступ к полям должен осуществляться без проблем. Такие требования есть наследие С. Где было популярно в следующей версии добавлять поля в структуры, при этом раскладка ее начала должна быть одинаковой для бинарной совместимости со старыми программами.
Здравствуйте, Bell, Вы писали:
D>>Так как пример написан — нет (есть private члены). Для того чтобы была гарантия последовательного размещения класс должен быть POD. На практике обычно будет работать.
B>А что насчет выравнивания?
В данном случае это не проблема, так как все члены одного типа. Вот если они будут разных типов, пусть даже одного размера — тогда могут быть проблемы.
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, dupamid, Вы писали:
D>>Так как пример написан — нет (есть private члены). Для того чтобы была гарантия последовательного размещения класс должен быть POD. На практике обычно будет работать.
B>А что насчет выравнивания?
объекты в структуре будут выравниваться так, как требуется для их типа, например, long — по 4 байтам, так же будет и в массиве.
Здравствуйте, dupamid, Вы писали:
D>В данном случае это не проблема, так как все члены одного типа. Вот если они будут разных типов, пусть даже одного размера — тогда могут быть проблемы.
Все это — не более чем наблюдаемое поведение одного или нескольких компиляторов. Что же касается стандарта, то ни о чем подобном там нет и речи:
9.2/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).
Здравствуйте, Bell, Вы писали:
D>>В данном случае это не проблема, так как все члены одного типа. Вот если они будут разных типов, пусть даже одного размера — тогда могут быть проблемы.
B>Все это — не более чем наблюдаемое поведение одного или нескольких компиляторов. Что же касается стандарта, то ни о чем подобном там нет и речи: B>
B>9.2/12
B>Nonstatic data members of a (nonunion) class declared without an intervening accessspecifier
B>are allocated so that later members have higher addresses within a class object. The order
B>of allocation of nonstatic data members separated by an accessspecifier is unspecified (11.1).
B>Implementation alignment requirements might cause two adjacent members not to be
B>allocated immediately after each other; so might requirements for space for managing
B>virtual functions (10.3) and virtual base classes (10.1).
B>
B>или я плохо искал?
Что конкретно ты считаешь не соответствует Стандарту или не требуется им. Могут ли быть дырки между подряд идущими членами класса одного типа? Если компилятор так поступает АБСОЛЮТНО всегда (во всех струтурах, чтобы они были совместимы по раскладке) то теортически могут — прямого запрета на это нет. Но это просто не имеет никакого смысла, поэтому, наверное, не удастся найти ни один такой компилятор.
Использовать это для оптимизации выравнивания нельзя, так как размер типа в массиве и самомого по себе должен быть одинаковым. Т.е. реализация, на которой sizeof типа long double 10 байт, а в масиве их кладут через 16 — для выравнивания, не соответсвует Стнадарту. Теперь, если вернуться у структурам, то получается что sizeof типов уже и так выровнены для нормального последовательного размещения, так что вставлять дыры смысла не имеет никакого.
Здравствуйте, dupamid, Вы писали:
D>Что конкретно ты считаешь не соответствует Стандарту или не требуется им. Могут ли быть дырки между подряд идущими членами класса одного типа? Если компилятор так поступает АБСОЛЮТНО всегда (во всех струтурах, чтобы они были совместимы по раскладке) то теортически могут — прямого запрета на это нет. Но это просто не имеет никакого смысла, поэтому, наверное, не удастся найти ни один такой компилятор.
Мое мнение таково: если стандарт чего-то не гарантирует, или тем паче прямо говорит о возможности несоблюдения неких свойств или поведения, то на такие свойства/поведение полагаться не стоит, даже если во всех доступных реализациях все "работает как надо". Тем более в ситуациях, когда есть простое "стандартное" решение.
Здравствуйте, Bell, Вы писали:
D>>Что конкретно ты считаешь не соответствует Стандарту или не требуется им. Могут ли быть дырки между подряд идущими членами класса одного типа? Если компилятор так поступает АБСОЛЮТНО всегда (во всех структурах, чтобы они были совместимы по раскладке) то теоретически могут — прямого запрета на это нет. Но это просто не имеет никакого смысла, поэтому, наверное, не удастся найти ни один такой компилятор.
B>Мое мнение таково: если стандарт чего-то не гарантирует, или тем паче прямо говорит о возможности несоблюдения неких свойств или поведения, то на такие свойства/поведение полагаться не стоит, даже если во всех доступных реализациях все "работает как надо". Тем более в ситуациях, когда есть простое "стандартное" решение.
Де-факто, такое размещение членов структур важно для низкоуровневого программирования именно для этого в Стандарте присутствуют POD и бинарная совместимость структур. Не смотря на кажущуюся вольность в размещение членов структур и битовых полей, ей никто не пользуется, так как это нарушит возможность использования языка для низкоуровневого программирования, где нужно строго контролировать раскладку структур и на самом деле реализации позволяют это делать, и не просто некоторые — а все. Выравнивание, раскладка структур, размеры типов, возможность копирования POD побайтно – это все части этой бинарной совместимости.
Что касается гарантий Стандарта, то мы практически постоянно пишем код, который балансирует на грани (а часто и за гранью) Стандарта. Это неизбежно. Например, практически любая программа содержит преобразования типов, которые является по-сути reinterpret_cast (возможно записанные через преобразования типов в старом стиле), поведение, которого явно оговорено что не портируемо. В этом смысле мне нравиться подход комитета по стандартизации С, есть понятие "common existing practice" и Стандарт старается ее поддерживать и пояснять, даже когда можно было бы сделать лучше ее нарушив. В C99Rational про это хорошо написано.
Касательно вопроса о раскладке структур там написано следующее:
The layout of structures is determined only to a limited extent:
— no hole may occur at the beginning.
— consecutive members occupy increasing storage addresses.
— if necessary, a hole is placed on the end to make the structure big enough to pack tightly into arrays and maintain proper alignment.
Since some existing implementations, in the interest of enhanced access time, leave internal holes larger than absolutely necessary, it is not clear that a portable deterministic method can be given for traversing a structure member by member.
Возможно путешествия по членам структуры на практике вызывает сложности только для членов разных типов, а не подряд идущих одинаковых.
Здравствуйте, Sergey, Вы писали:
d>> Использовать это для оптимизации выравнивания нельзя, так как размер d>> типа в массиве и самомого по себе должен быть одинаковым. Т.е. d>> реализация, на которой sizeof типа long double 10 байт, а в масиве их d>> кладут через 16 — для выравнивания, не соответсвует Стнадарту. Теперь, d>> если вернуться у структурам, то получается что sizeof типов уже и так d>> выровнены для нормального последовательного размещения, так что d>> вставлять дыры смысла не имеет никакого.
S>Не так. Есть у нас10-байтный long double, в массив его приходится класть S>подряд — чтоб по стандарту, а в структуру имеем право класть с дырками — и S>так и делаем, для оптимизации. Где противоречие?
А почему это его sizeof будет равен 10???
Можещь посмотреть на gcc под Windows — 12, на Intel C++ (/Qlong_double) — 16.
#include <stdio.h>
struct S
{
long double d1;
long double d2;
};
int main()
{
printf("sizeof(long double) == %d\n", sizeof(long double));
printf("sizeof(S) == %d\n", sizeof(S));
}
Hello, dupamid!
You wrote on Wed, 11 Aug 2004 14:24:10 GMT:
S>> Не так. Есть у нас10-байтный long double, в массив его приходится S>> класть подряд — чтоб по стандарту, а в структуру имеем право класть с S>> дырками — и так и делаем, для оптимизации. Где противоречие?
d> А почему это его sizeof будет равен 10???
А почему бы и нет? Мы же рассматриваем гипотетическую ситуацию. Но если
нужна причина, пусть будет потому, что это для сопроцессора "родная" длина
слова.
d> Можещь посмотреть на gcc под Windows — 12, на Intel C++ (/Qlong_double) d> — 16.
И что с того? Под Win 16 у кучи компиляторов long double 80-bit был.
With best regards, Sergey.
Posted via RSDN NNTP Server 1.9 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Евгений Коробко wrote:
> class Vect > { > ... > public: > double operator [] (int i) const {return *(&x+i);}; > private: > double x,y,z; > }; > > Собственно, вопрос вызывает то, можно ли быть уверенным, что x,y,z будут расположены в памяти подряд?
Вопрос достаточно тонкий и заставляет хмурить брови, когда смотришь на такой код.
ME>Почему бы не написать простой и безопасный код?
Потому что получается либо простой, либо безопасный. Потому как если обращаться к членам через m_Items[x], то формула, например, векторного умножения будет выглядеть просто страшно.
Сейчас так:
return Vect(v1.m_X*v2.m_Z-v1.m_Z*v2.m_Y, v1.m_Z*v2.m_X-v1.m_X*v2.m_Z,
v1.m_Y*v2.m_Z-v1.m_Z*v2.m_Y);
Евгений Коробко wrote:
> Потому что получается либо простой, либо безопасный. Потому как если обращаться к членам через m_Items[x], то формула, например, векторного умножения будет выглядеть просто страшно. > > Сейчас так: > return Vect(v1.m_X*v2.m_Z-v1.m_Z*v2.m_Y, v1.m_Z*v2.m_X-v1.m_X*v2.m_Z, > v1.m_Y*v2.m_Z-v1.m_Z*v2.m_Y); > > А будет так: > > return Vect(v1.m_Items[x]*v2.m_Items[z]-v1.m_Items[z]*v2.m_Items[y], v1.m_Items[z]*v2.m_Items[x]-v1.m_Items[x]*v2.m_Items[z], > v1.m_Items[y]*v2.m_Items[z]-v1.m_Items[z]*v2.m_Items[y]);
Лично я разницы не вижу — и тот и другой кусок страшен.
Здравствуйте, dupamid, Вы писали:
D>Здравствуйте, Sergey, Вы писали:
d>>> Можещь посмотреть на gcc под Windows — 12, на Intel C++ (/Qlong_double) — 16.
S>>И что с того? Под Win 16 у кучи компиляторов long double 80-bit был.
D>Так и у Win32 это все тот же 80-битный long double (в этом смысле размеры типов у FPU не изменились), его размер увеличен для выравнивания.
Именно в этом и поинт.
Стандарт, вроде как, жестко(абсолютно) не привязывает ни размеры кардинальных типов ни выравнивания, все это отдано на откуп разработчикам компилятора.
D>Де-факто, такое размещение членов структур важно для низкоуровневого программирования именно для этого в Стандарте присутствуют POD и бинарная совместимость структур. Не смотря на кажущуюся вольность в размещение членов структур и битовых полей, ей никто не пользуется, так как это нарушит возможность использования языка для низкоуровневого программирования, где нужно строго контролировать раскладку структур и на самом деле реализации позволяют это делать, и не просто некоторые — а все. Выравнивание, раскладка структур, размеры типов, возможность копирования POD побайтно – это все части этой бинарной совместимости.
Пример из личной практики.
Несколько лет назад обратились ко мне коллеги из параллельной организации с вопросом: "А почему мы не можем получить из железяки данные", они использовали POD-struct ( точно не приведу его — не помню ) но в нем была, как здесь назвали "дырка", и получали они иногда мусор, а и ногда кору от ядра
Спасло коллег явное использования выравнивания 1.
К чему это ? Да к тому, что гарантия валидности копирования memcpy ничего не грит о выравнивании.
Да и проблема возникла на железном уровне
Здравствуйте, Alex Alexandrov, Вы писали:
AA>Вмешаюсь в беседу, извините. Почему-то все говорят про Стандарт, забывая о том, что это лишь один из документов, регулирующих поведение компилятора. Когда мы говорим о C-структурах, т.е. о типах, поля которых используются напрямую, то большее значение имеет другой документ: ABI (Application Binary Interface) спецификация. Именно она регулирует подобные вещи в большей степени, стремясь к гарантии, что вы можете использовать библиотеки и заголовочные файлы, полученные с помощью другого компилятора.
AA>В частности, именно Intel 386 ABI запрещает компилятору сделать "что-то подобное", приведенное выше.
А можешь дать ссылочку на этот документ? А то google находит его только для System V, а мне бы хотелось для Windows/Linux или (лучше) не зависымый от опреационной системы. Для Itanium или EM64T/AMD64 это общедоступные документы.
AA>Вмешаюсь в беседу, извините. Почему-то все говорят про Стандарт, забывая о том, что это лишь один из документов, регулирующих поведение компилятора. Когда мы говорим о C-структурах, т.е. о типах, поля которых используются напрямую, то большее значение имеет другой документ: ABI (Application Binary Interface) спецификация. Именно она регулирует подобные вещи в большей степени, стремясь к гарантии, что вы можете использовать библиотеки и заголовочные файлы, полученные с помощью другого компилятора.
In computer software, an application binary interface (ABI) describes the low-level interface between an application program and the operating system, between an application and its libraries, or between component parts of the application. An ABI differs from an application programming interface (API) in that an API defines the interface between source code and libraries, so that the same source code will compile on any system supporting that API, whereas an ABI allows compiled object code to function without changes on any system using a compatible ABI.
И исходя из этого становится ясно почему все говорят о Стандарте:
Решение, которое отвечает стандарту, будет переносимым( на компиляторы поддерживающие стандарт ). В свою очередь решения затаченное под Intel Binary Compatibility Standard (iBCS) может быть н6еперносимо на другие платформы.
А об ABI будут думать разрабочики компилятора под конкретные программно-аппаратные платформы. ИМХО в большинстве задач только разработчики компиляторов и должны думать ABI. И очень редко должны задумываться рпзрпботчики ПО
... << RSDN@Home 1.1.4 stable rev. 510>>
Re: Корректен ли код
От:
Аноним
Дата:
28.11.05 10:28
Оценка:
Здравствуйте, Евгений Коробко, Вы писали:
ЕК>class Vect ЕК>{ ЕК>... ЕК>public: ЕК> double operator [] (int i) const {return *(&x+i);}; ЕК>private: ЕК> double x,y,z; ЕК>};
ЕК>Собственно, вопрос вызывает то, можно ли быть уверенным, что x,y,z будут расположены в памяти подряд?
А почему бы (чтобы не возникали такие вопросы и не было зависимости от используемого компилятора) не написать просто
Здравствуйте, Аноним, Вы писали:
А>А почему бы (чтобы не возникали такие вопросы и не было зависимости от используемого компилятора) не написать просто
А>class Vect А>{ А>... А>public: А> double operator [] (int i) const {return x[i];}; А>private: А> double x[3]; А>};
читай внимательней предыдущие посты — человеку не нравится обращаться к значениям по индексу, хочется символьных обозначений %)
А>Олег Р.
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Здравствуйте, srggal, Вы писали:
S>И исходя из этого становится ясно почему все говорят о Стандарте: S> Решение, которое отвечает стандарту, будет переносимым( на компиляторы поддерживающие стандарт ). В свою очередь решения затаченное под Intel Binary Compatibility Standard (iBCS) может быть н6еперносимо на другие платформы.
S>А об ABI будут думать разрабочики компилятора под конкретные программно-аппаратные платформы. ИМХО в большинстве задач только разработчики компиляторов и должны думать ABI. И очень редко должны задумываться рпзрпботчики ПО
Разработчики ПО обязаны знать об ABI. Когда ты пишешь библиотеку под Unix, тебе надо понимать это хотя бы для того, чтобы понять, является ли новая версия твоей библиотеки ABI-совместимой с предыдущей, и какую цифру в версии таки надо менять (major/minor/patch). Когда начинаются глюки с С++ рантаймом также надо знать, что такое ABI и когда у GCC он поменялся. И т.д.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
It's kind of fun to do the impossible (Walt Disney)
Здравствуйте, dupamid, Вы писали:
D>Здравствуйте, Alex Alexandrov, Вы писали:
AA>>Вмешаюсь в беседу, извините. Почему-то все говорят про Стандарт, забывая о том, что это лишь один из документов, регулирующих поведение компилятора. Когда мы говорим о C-структурах, т.е. о типах, поля которых используются напрямую, то большее значение имеет другой документ: ABI (Application Binary Interface) спецификация. Именно она регулирует подобные вещи в большей степени, стремясь к гарантии, что вы можете использовать библиотеки и заголовочные файлы, полученные с помощью другого компилятора.
AA>>В частности, именно Intel 386 ABI запрещает компилятору сделать "что-то подобное", приведенное выше.
D>А можешь дать ссылочку на этот документ? А то google находит его только для System V, а мне бы хотелось для Windows/Linux или (лучше) не зависымый от опреационной системы. Для Itanium или EM64T/AMD64 это общедоступные документы.
Честно сказать, я привел цитату из того же System V ABI. Что-то мне подсказывает, что GCC ABI корнями идет оттуда. Но не смог найти явной информации.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
It's kind of fun to do the impossible (Walt Disney)
Re: Корректен ли код
От:
Аноним
Дата:
30.11.05 08:40
Оценка:
ЕК>class Vect ЕК>{ ЕК>... ЕК>public: ЕК> double operator [] (int i) const {return *(&x+i);}; ЕК>private: ЕК> double x,y,z; ЕК>};
ЕК>Собственно, вопрос вызывает то, можно ли быть уверенным, что x,y,z будут расположены в памяти подряд?
Если мне не изменяет память, такая гарантия есть, если это будет не class а struct
Здравствуйте, Аноним, Вы писали:
А>Если мне не изменяет память, такая гарантия есть, если это будет не class а struct
Можно привести ссылки на первоисточники?
А об ABI будут думать разрабочики компилятора под конкретные программно-аппаратные платформы. ИМХО в большинстве задач только разработчики компиляторов и должны думать ABI. И очень редко должны задумываться рпзрпботчики ПО
Думаю Вы согласитесь, что "очень редко" как раз описываеи привеленную Вами ситуацию
Здравствуйте, srggal, Вы писали:
S>Здравствуйте, jazzer, Вы писали:
S>[]
S>Немного оторвано от контекста дискуссии, но тем не менее
S>ГМ, в целом, я писал здесь
S>А об ABI будут думать разрабочики компилятора под конкретные программно-аппаратные платформы. ИМХО в большинстве задач только разработчики компиляторов и должны думать ABI. И очень редко должны задумываться рпзрпботчики ПО
S>Думаю Вы согласитесь, что "очень редко" как раз описываеи привеленную Вами ситуацию
S>
Согласен, правда, в нашем случае это очень редко тянется уже год и будет тянуться, пока эти приложения не будут переписаны на других движках (а в некоторых случаях этих других движков и не существует, так что остается только реализация библиотеки вручную).
Еще пример — у тебя есть приложение, собранное из нескольких библиотек плюс то, что ты написал. Так вот, собирая все это дело вместе, имеет смысл помнить, что каждый компонент мог быть собран со своими ключами компиляции, а эти ключи, в принципе, могут конфликтовать (хотя это, конечно, было бы очень нехорошо со стороны разработчиков компилятора). По-моему, у VC++ или у Борланда была опция, при помощи которой которой можно было управлять бинарной реализацией множественного наследования, и предлагалось там варианта 4, по-моему. Насколько я понимаю, эти варианты были бинарно несовместимыми, а это означало, что если тебе захотелось изменить эту опцию, тебе в общем случае придется пересобрать все библиотеки, а не только парочку объектников, которые тебя интересуют. И хорошо, если все библиотеки у тебя есть в исходниках. А если нет? Ты проклянешь все в поисках причины глюков и путей их объезда.
S>>А об ABI будут думать разрабочики компилятора под конкретные программно-аппаратные платформы. ИМХО в большинстве задач только разработчики компиляторов и должны думать ABI. И очень редко должны задумываться рпзрпботчики ПО
J>Еще пример — у тебя есть приложение, собранное из нескольких библиотек плюс то, что ты написал. Так вот, собирая все это дело вместе, имеет смысл помнить, что каждый компонент мог быть собран со своими ключами компиляции, а эти ключи, в принципе, могут конфликтовать (хотя это, конечно, было бы очень нехорошо со стороны разработчиков компилятора). По-моему, у VC++ или у Борланда была опция, при помощи которой которой можно было управлять бинарной реализацией множественного наследования, и предлагалось там варианта 4, по-моему. Насколько я понимаю, эти варианты были бинарно несовместимыми, а это означало, что если тебе захотелось изменить эту опцию, тебе в общем случае придется пересобрать все библиотеки, а не только парочку объектников, которые тебя интересуют. И хорошо, если все библиотеки у тебя есть в исходниках. А если нет? Ты проклянешь все в поисках причины глюков и путей их объезда.
Дык что да, то да
Но опять, в контексте темы отпика и первого сообщения того, с кем я спорил
, а там как раз идет речь именно о смене ABI.
S>>Я вот о чем: этот спор в контексте темы топика
J>в контексте темы топика нам от ABI достаточно sizeof
И чем нам здесь
Для того что-бы забить на выравнивание и статически проверять при компялиции валидность утверждения ?
ИМХО — не выход.
J>>>P.S. Мы ведь на "ты" здесь, да? S>>По правилам вроде на Вы
S>>
J>ОК, прошу прощения за тыканье! J>Постараюсь запомнить, что с Вами надо на Вы Ну или на брудершафт
Ах, оставьте...
Здравствуйте, srggal, Вы писали:
S>достаточно sizeof
S>Для того что-бы забить на выравнивание и статически проверять при компялиции валидность утверждения ? S>ИМХО — не выход.
Ну почему же
если sizeof(массив) == sizeof(структура) — значит, нечему там больше быть, кроме этих несчастных членов в порядке их объявления в классе.
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, srggal, Вы писали:
S>>достаточно sizeof
S>>Для того что-бы забить на выравнивание и статически проверять при компялиции валидность утверждения ? S>>ИМХО — не выход.
J>Ну почему же
J>если sizeof(массив) == sizeof(структура) — значит, нечему там больше быть, кроме этих несчастных членов в порядке их объявления в классе.
Я же написал ИМХО
Потому что нет гарантии что в следующей версии компилятора, или на другом компиляторе все будект ОК ( ABI прнимаешь )
ИМХО лучше, по возможности, придерживаться стандарта
ЗЫ
Можно не отвечать ибо еще немного и нас можно в философию отправлять
Здравствуйте, srggal, Вы писали:
S>Здравствуйте, Alex Alexandrov, Вы писали:
AA>>Разработчики ПО обязаны знать об ABI. Когда ты пишешь библиотеку под Unix, тебе надо понимать это хотя бы для того, чтобы понять, является ли новая версия твоей библиотеки ABI-совместимой с предыдущей, и какую цифру в версии таки надо менять (major/minor/patch). Когда начинаются глюки с С++ рантаймом также надо знать, что такое ABI и когда у GCC он поменялся. И т.д.
S>Насколько сильно я ошибусь предположив что руководствуясь стандартом языка С/С++ я могу абстрагироваться от АБИ?
S>Если Вас не затруднит — приведите пример когда с точки зрения стандарта код будет well-formed, но при этом Он не будет удовлетворять AАБИ.
S>Стандарт ИМХО для того и писан, чтобы абстрагироваться от платформы
Я смотрю, вы тут уже с Джаззером поговорили. В общем-то, все по делу. Если все происходит в пределах одного модуля, и не надо взаимодействовать ни с кем, кто потенциально может быть скомпилирован хотя бы с другими ключами компиляции, то Стандарта достаточно. В реальном мире ваше "Редко" приходится постоянно держать в голове при проектировании более или менее серьезного интерфейса.