Здравствуйте, SergeCpp, Вы писали:
SC>Здравствуйте, Lorenzo_LAMAS, Вы писали:
SC>...
SC>>>К сожалению, НЕ идентична... L_L>>Если вас не затруднит, посмотрите для начала приведенную мною в этом обсуждении цитату из стандарта, после этого, продолжим (если будет охота)
SC>Да, признаю, в этом случае, вероятно, так SC>(не пишу "наверняка так", потому что мне нужно думать - SC>ну торможу помаленьку...)
SC>Но самое главное, из за чего мой вопрос возник — у меня НЕ "same class"...
я был осторожен и написал "при таких типах объектов"
У тебя все объекты типа
SomeType a( 1 );
SomeType b ( a ); // семантика этих двух строк
SomeType c = a; // сильно отличается
SC>"...if the function is a constructor, SC>the call initializes a temporary of the destination type..."
а вот этот фрагмент-то относится к случаю, когда инициализатор (source) имеет не тот тип, что destination
SC>Вот в чём мой страх, несмотря на
SC>"...In certain cases, an implementation is permitted to eliminate SC>the copying inherent in this direct-initialization by constructing SC>the intermediate result directly into the object being initialized..."
это относится к виду
SomeType a = 1;
Здесь может быть просто вызов SomeType::SomeType(int)
и не быть создания промежуточнух копий, но это не относится к тому примеру, к которому я пристал SC>С уважением, Сергей Смирнов
SC>P.S. Ничего личного — это ТЕХНИЧЕСКИЙ вопрос (НЕ мой выпендрёж)
Of course, the code must be complete enough to compile and link.
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, CrystaX, Вы писали:
CX>>
CX>>#include <iostream>
CX>>int main()
CX>>{
CX>> size_t n = 1;
CX>> int ok(int(n));
CX>> std::cout << ok << std::endl; // А вот здесь уже неверно.
CX>> // ok - это объявление функции, возвращающей int и принимающей также int.
CX>> // Выражение int(n) по синтаксису является списком формальных параметров.
CX>> return 0;
CX>>}
CX>>
J>а чего ж неверного распечатается адрес функции
В данном коде нет. Функции-то нет! Есть только ее объявление.
Здравствуйте, CrystaX, Вы писали:
CX>Здравствуйте, jazzer, Вы писали:
J>>Здравствуйте, CrystaX, Вы писали:
CX>>>
CX>>>#include <iostream>
CX>>>int main()
CX>>>{
CX>>> size_t n = 1;
CX>>> int ok(int(n));
CX>>> std::cout << ok << std::endl; // А вот здесь уже неверно.
CX>>> // ok - это объявление функции, возвращающей int и принимающей также int.
CX>>> // Выражение int(n) по синтаксису является списком формальных параметров.
CX>>> return 0;
CX>>>}
CX>>>
J>>а чего ж неверного :) распечатается адрес функции :)
CX>В данном коде нет. Функции-то нет! Есть только ее объявление. :)
А, ну да, не слинкуется.
Но скомпилиться — скомпилится, и если объектник в таком виде войдт в библиотеку, а потом кто-нть решит написать свою прогу с этой библиотекой... :))))
Здравствуйте, SergeCpp, Вы писали:
SC>Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>>Вот как определен if в грамматике L_L>>
L_L>>6.4 Selection statements [stmt.select]
L_L>>1 Selection statements choose one of several flows of control.
L_L>>selection-statement:
L_L>>if ( condition ) statement
L_L>>if ( condition ) statement else statement
L_L>>switch ( condition ) statement
L_L>>condition:
L_L>>expression
L_L>>type-specifier-seq declarator = assignment-expression//т.е. нужен именно такой инициализатор = что-то
SC>Вот что говорит стандарт ISO/IEC 14882
SC>5. If a condition can be syntactically resolved as
SC> either an expression or the declaration of a local name,
SC> it is interpreted as a declaration.
SC>Согласно 5, if( int ok( 123 ) ) — допустимо, SC>хотя ЯВНЫМ образом и не указано в 1...
SC>"...can..."
SC>int ok( 123 )
SC>"... be syntactically resolved as... ...declaration..." ?
SC>очевидно, да
SC>Самое большее, что здесь есть — так это некоторая НЕДОГОВОРЁННОСТЬ SC>о случае "if( int ok( 123 ) )", но считать его ОШИБКОЙ...
Допустимый синтаксис описан в грамматике. int ok(123) этой грамматике не соответствует, поэтому в текущей редакции стандарта это ошибка. Пиши defect report, или как это называется…
А так вообще нужно делать классы, которые предполагается вот так использовать в if, копируемыми, и писать:
if (Resource r = Resource(хрр, брр))
Хороший оптимизатор это копирование выоптимизирует, а плохому можно помочь идиомой pimpl.
Здравствуйте, Centaur, Вы писали:
C>Допустимый синтаксис описан в грамматике. int ok(123) этой грамматике не соответствует, поэтому в текущей редакции стандарта это ошибка. Пиши defect report, или как это называется…
C>А так вообще нужно делать классы, которые предполагается вот так использовать в if, копируемыми, и писать: C>
C>if (Resource r = Resource(хрр, брр))
C>
C>Хороший оптимизатор это копирование выоптимизирует, а плохому можно помочь идиомой pimpl.
Описан в двух указанных мною местах по-разному...
А насчёт "выоптимизирует" — а что, если
СЕМАНТИКА копирования
в моём классе КОРЕННЫМ ОБРАЗОМ ОТЛИЧАЕТСЯ
от семантики КОНСТРУИРОВАНИЯ ?
S> 5. If a condition can be syntactically resolved as
S> either an expression or the declaration of a local name,
S> it is interpreted as a declaration.
S> Согласно 5, if( int ok( 123 ) ) — допустимо, S> хотя ЯВНЫМ образом и не указано в 1...
Нет, п. 5 говорит совсем о другом (см. ниже). Вообще же, грамматика
задает множество возможных предложений языка. Положения, выраженные
текстом, могут дополнительно ограничивать это множество. Т.е. все,
что через фильтр грамматики не проходит, дальнейшими текстовыми
пояснениями просто не учитывается.
S> "...can..." S> int ok( 123 ) S> "... be syntactically resolved as... ...declaration..." ? S> очевидно, да
Так вот, возвращаясь к п. 5. Нельзя его так резать. Наличие "или" в нем
существенно. Этот пункт говорит о том, что в случае наличия неоднозначности, не разрешимой грамматикой, т.е. если некоторая конструкция может быть
разобрана и как выражение, и как объявление, компилятор должен выбрать
вариант с объявлением. Пример:
struct C
{
C(int);
C& operator =(int);
operator bool() const;
};
int main()
{
int i = 10;
if( C(i) = 10 )
{
// ++i;return 1;
}
}
В данном случае, если смотреть только на грамматику, игнорируя текстовые
правила стандарта, то выделенная строка может быть как выражением ("создать
временный объект типа C, проинициализированный переменной i, и присвоить
ему значение 10"), либо же объявлением ("объявить переменную i типа C,
и проинициализировать ее значением 10").
Если бы компилятор выбирал первый вариант, то можно было бы раскомментировать
строку с "++i", т.к. в этом случае она бы означала инкремент переменной int i,
определенной чуть выше. Однако, т.к. стандарт предписывает компилятору выбрать
именно второй вариант, если раскомментировать эту строку, программа станет
невалидной:
Comeau C/C++ 4.3.3 (Aug 6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing. All rights reserved.
MODE:strict errors C++
"ComeauTest.c", line 13: error: no operator "++" matches these operands
operand types are: ++ C
++i;
^
"ComeauTest.c", line 10: warning: variable "i" was declared but never referenced
int i = 10;
^
1 error detected in the compilation of "ComeauTest.c".
S> Самое большее, что здесь есть — так это некоторая НЕДОГОВОРЁННОСТЬ S> о случае "if( int ok( 123 ) )", но считать его ОШИБКОЙ...
Нет там никакой недоговоренности, если не выдавать желаемое за действительное,
а просто читать стандарт, как он написан.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
SergeCpp,
C>> Допустимый синтаксис описан в грамматике. int ok(123) этой грамматике C>> не соответствует, поэтому в текущей редакции стандарта это ошибка. Пиши C>> defect report, или как это называется…
S> Описан в двух указанных мною местах по-разному...
Просто синтаксис задан грамматикой неоднозначно, текстовое дополнение эту
неоднозначность разрешает. Никакого противоречия там нет.
S> А насчёт "выоптимизирует" — а что, если S> СЕМАНТИКА копирования S> в моём классе КОРЕННЫМ ОБРАЗОМ ОТЛИЧАЕТСЯ S> от семантики КОНСТРУИРОВАНИЯ ?
В этом случае выполнение программы уже может приводить к неоднозначностям,
т.к. стандарт в достаточном количестве мест содержит разрешения добавлять/
убирать временные объекты.
Ты можешь привести конкретный пример, где тебе существенно создание
дополнительного временного объекта в подобном случае?
И почему этот случай нельзя "разрулить" таким образом?
{
MyClass m(init);
if (m)
{
. . .
}
}
S> Тут нужно быть на 100 % уверенным
В обоих случаях происходит конструирование. В одном из случаев может произойти
конструирование дополнительного временного объекта.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Ты можешь привести конкретный пример, где тебе существенно создание ПК>дополнительного временного объекта в подобном случае?
Конкретный пример у меня дома...
Но ведь СОЗДАНИЕ ДОПОЛНИТЕЛЬНОГО — это же очевидно — ИЗЛИШНЕ!
ПК>И почему этот случай нельзя "разрулить" таким образом? ПК>
S>> Можно "разрулить" — НО
S>> 1. "m" ОСТАЁТСЯ в scope после "if" S>> 2. ВАЖНО — "m" в Вашем примере "m" НЕ УНИЧТОЖИТСЯ в конце "if"
ПК>Я специально окружил предлагаемую замену фигурными скобками. Единственное ПК>место, где будет разница -- if ... else ...
Здравствуйте, SergeCpp, Вы писали:
SC>А насчёт "выоптимизирует" — а что, если SC>СЕМАНТИКА копирования SC>в моём классе КОРЕННЫМ ОБРАЗОМ ОТЛИЧАЕТСЯ SC>от семантики КОНСТРУИРОВАНИЯ ?
Здравствуйте, Centaur, Вы писали:
C>Здравствуйте, SergeCpp, Вы писали:
SC>>А насчёт "выоптимизирует" — а что, если SC>>СЕМАНТИКА копирования SC>>в моём классе КОРЕННЫМ ОБРАЗОМ ОТЛИЧАЕТСЯ SC>>от семантики КОНСТРУИРОВАНИЯ ?
C>Очень плохо. Я умываю руки.
Ну а если этот класс — база данных ?
КОПИРОВАТЬ её я не хочу...
Хоть это и несколько указателей
(а со ссылками — ТЕМ БОЛЕЕ не очень)...
Здравствуйте, SergeCpp, Вы писали:
SC>Здравствуйте, Centaur, Вы писали:
C>>Здравствуйте, SergeCpp, Вы писали:
SC>>>А насчёт "выоптимизирует" — а что, если SC>>>СЕМАНТИКА копирования SC>>>в моём классе КОРЕННЫМ ОБРАЗОМ ОТЛИЧАЕТСЯ SC>>>от семантики КОНСТРУИРОВАНИЯ ?
C>>Очень плохо. Я умываю руки.
SC>Ну а если этот класс — база данных ?
SC>КОПИРОВАТЬ её я не хочу...
Если это действительно база данных, то есть большая коллекция объектов, то конструировать её посреди программы ты тоже не хочешь.
SC>Хоть это и несколько указателей SC>(а со ссылками — ТЕМ БОЛЕЕ не очень)...
А если это абстракция подключения к базе данных — то его вполне можно сделать копируемым или, скажем, перемещаемым (как std::auto_ptr). Что до ссылок, то их можно заменить указателями без большого труда.
...
SC>>Ну а если этот класс — база данных ?
SC>>КОПИРОВАТЬ её я не хочу...
C>Если это действительно база данных, то есть большая коллекция объектов, то конструировать её посреди программы ты тоже не хочешь.
А кто сказал, что ПОСРЕДИ ?
SC>>Хоть это и несколько указателей SC>>(а со ссылками — ТЕМ БОЛЕЕ не очень)...
C>А если это абстракция подключения к базе данных — то его вполне можно сделать копируемым или, скажем, перемещаемым (как std::auto_ptr). Что до ссылок, то их можно заменить указателями без большого труда.
...вполне можно... // некрасиво...
...без большого труда... // а МАЛЕНЬКИЙ труд тоже не нужен...
Здравствуйте, Lorenzo_LAMAS, Вы писали:
S>>Offtopic: S>>Кстати. У меня последний стандарт от 1998 года. Есть более свежий? Если да, то где взять?
L_L>Такие вопросы не приветствуются L_L>давай мыло
Здравствуйте, SergeCpp, Вы писали:
SC>Здравствуйте, Centaur, Вы писали:
SC>>>Ну а если этот класс — база данных ?
SC>>>КОПИРОВАТЬ её я не хочу...
C>>Если это действительно база данных, то есть большая коллекция объектов, то конструировать её посреди программы ты тоже не хочешь.
SC>А кто сказал, что ПОСРЕДИ ?
А если бы он рождался в начале программы и жил бы всё время её выполнения, то там бы был не if, а исключение бы бросалось. А if говорит мне о том, что объект короткоживущий, легко конструируемый, и не особо важный для функционирования программы.