progmachine
Все эти "наврядли" и "если предположить" - вот что НЕПРАВИЛЬНО.
Ghost2
Если тебе не нравится "наврядли" пункта б, тогда пристально смотри на пункт в.
А пункт б лишь оптимизационное замечание, т.е. я бы так сделал.
progmachine
Мне ваще-то все очень нравится, тока в стандарте написано, что передавать нужно по значению. А выше я просто объяснил, почему нужно делать именно так.
Что касается векторов с элементами безумных размеров, сам наверняка знаешь: заставь дурака Богу молиться, он и лоб расшибет.
Ghost2
сорри за занудство... в каком именно стандарте? ссылочку можно?
>>А выше я просто объяснил, почему нужно делать именно так
объяснил. но неубедительно - по коду выходит, что это строго необязательно... впрочем, это потом... после того, как стандарт почитаю...
Lion007
>в каком именно стандарте? ссылочку можно?
В C++ Standard - ANSI ISO IEC 14882 2003. Он ваще-то денег стоит. Но тебе по знакомству: http://anatolix.naumen.ru/files/books/CPPStandard2003.zip
>объяснил. но неубедительно
Да я сам толком не могу придумать отчего так написано, тем более что insert принимает const T& (но - внутри его все-равно копирует :O). Очевидно, что потенциальный косяк в конкретной реализации может произойти по причине const T&. И его не может произойти если это T. Стандарт потенциальными косяками не занимается, поэтому я поискал в нете по данному вопросу и нашел пару комментов про т.н. self-referential fills (не от кого-нибудь, а от самого главного писателя STL для VC, мистического P.J. Plauger'a). Что такое и с чем едят не знаю - этот гад намекнул и слился.
>впрочем, это потом... после того, как стандарт почитаю...
А объяснений в стандарте днем с огнем не найдешь. Так надо и все...
Ghost2
спасибо... действительно - у них там нарисована передача по значению...
мдя... странно это все... но, имхо - просто глупость. математически доказать пока не могу - все-таки много простора для извратов - но объект, который нельзя передавать по констовой ссылке, едва ли будет удовлетворять требованиям того же стандарта к содержимому вектора... ладно, фиг с ними со всеми... пусть народ и дальше мучается с выровнеными объектами...
зы : а я буду брутальным и бессердечным. и тупо поправлю ресайз в системном хидере.
Lion007
А я буду еще брутальнее и буду юзать STLport =) там кстати второй параметр у ресайза через константную сцылку передается ;)
Lion007
resize это очень хардкорный метод. Я, например, очень редко его использую, а если и использую - то в самых тривиальных ситуациях (POD типы, указатели или в тех местах, где на скорость наплевать). Так что буста от правки стандартных хедеров не получу никакого (думаю, что у тебя та-же фигня получится). Только расстройство одно будет.
Если честно, уверен, что ни в одном толково написанном коде о таких вещах даже не задумываются. Есть, конечно, люди, которые пишут как в "коде для размышления" (подумать действительно есть над чем :)
vector<vector<C3DObject> > hundred; hundred.resize(100, ...);
вот пусть они, молодые и горячие, и борются со стандартом.
eHomo
Надо сказать, что в STLPort (в плане resize), все точно так же, как и у Dinkumware.
Ghost2
я не говорю о бусте, я говорю о принципиальной возмодности использования std::vector для типов с гарантированным выравниванием
class __declspec(align( 16)) Vector { public: __m128 vec; // правильные new, delete и прочие std:allocator<Vectr> прилагаются. };
std::vector<Vector> a;
и будет хренакс. потому что компилятор ФИЗИЧЕСКИ не может обеспечить передачу на стэке переменной с гарантированным выравниванием. точнее (теоретически) я могу представить, как это проделать. но VS этого не умеет. то есть вообще. обидно, досадно, но факт...
>> правка
в gcc - const T&. что под виндой, что под макосью.
Lion007
std::vector<__m128> a;
)))))))))
Ghost2
улыбнуло... но, к сожалению, не выход...
class __declspec(align( 16)) Ray { public: __m128 org; __m128 dir; // правильные new, delete и прочие std:allocator<Vectr> прилагаются. }; std::vector<Ray>
ладно, это все шуточки, но не по теме...
а вот про глюк с _mm_sqrt_ss что-нибудь известно? ситуация (с 6 по 2005) такая
__m128 __fascall do_sqrt_ps(__m128 a) { return _mm_sqrt_ps( a); }
дает нормальный ассемблерный код
sqrtps xmm0, xmm0
ret
функция
__m128 __fascall do_sqrt_ss(__m128 a) { return _mm_sqrt_ss( a); }
порождает нечто невменяемое... организуется стэк-фрэйм(причем с выравниванием), после этого xmm регистр копируется в локальную переменную, потом ровно из нее же достается и вычисляется sqrt_ss... жуть, мрак, логики никакой... и все это вместо
sqrtss xmm0, xmm0
ret
или это тоже по стандарту? 8)
Lion007
>но, к сожалению, не выход...
Вот это и есть "баг". Почему __m128 можно запихнуть в вектор, а копипаст этого же __m128, только с именем __m128_my нельзя? Потому что это наверняка не определение, а встроеный тип. Делают, блин, что хотят....
Ghost2
> Что касается векторов с элементами безумных размеров, сам наверняка знаешь: заставь дурака Богу молиться, он и лоб расшибет.
> вот пусть они, молодые и горячие, и борются со стандартом.
Я в подобном случае, предпочел бы хранить в векторе указатели. У всех стандартных контейнеров есть требования, что элементы должны свободно копироваться, а значит они и будут копироваться, но не в таком тривиальном случае. Вообще сам Страуструп в своей книге пишет, что объекты в функции должны передаваться по константной ссылке всегда и везде, поскольку а) иное может привести к "срезанию объекта", если функции может передаться объект класса потомка от типа аргумента с перегруженными виртуальными методами и мы получим не то, чего хотели и долго будем искать ошибку, б) если функция - шаблон, то тип может оказаться не тривиальным (типа инт), а тяжелым и долго копирующимся (особено если речь идет о хардкорном абстрактном программировании, где это сложно контролировать). А о проблеме "self-referential fills", по логике должен заботиться сам контейнер, чтобы гарантировать заявленную гибкость и скорость работы STL.
Lion007
> и будет хренакс. потому что компилятор ФИЗИЧЕСКИ не может обеспечить передачу на стеке переменной с гарантированным выравниванием.
Пробовал это делать в VS2003, она отлично работает с выравниваемыми данными в стеке. На счет других компиляторов не знаю...
progmachine
struct __declspec(align( 16)) Foo //struct __attribute__((aligned(16))) Foo /* for GCC */ { int a, b, c, d; }; int func( Foo foo) { return foo.a; }
VS6, VS.NET (который 7.0), VS2005 - error C2719: 'foo': formal parameter with __declspec(align('16')) won't be aligned
про 2003 ничего не скажу - под руками нет
gcc сожрал. и, насколько я могу судить по ассемблерному коду - таки выровнял на стеке...
*** чуть позже
int func2(Foo foo, int a, Foo foo2) { printf( "%p, %p, %p\n", &foo, &a, &foo2); return foo.a; }
gcc-таки облажался... первый параметр честно выровнял, а вот дальше...
напечаталось : 0022FF10, 0022FF20, 0022FF24
с третьим параметром - беда, однако
Тема в архиве.