new(R);
От: Аноним  
Дата: 22.07.08 07:20
Оценка:
Есть ль какой то смысл в том что, данные ниже, две записи оператора new выполняют одно и тоже?
Что компилятор из второго варианта просто убирает скобки, или такая форма тоже правальная и эквивалентна первой?
Я спрашиваю это потому, что это очень похоже на оператор размещения new, может быть это он так замаскировался и размещает "ничего" в какой то постоянной области (R), в которой уже живет R.

R *pr1=new R;
R *pr2=new(R);
Re: new(R);
От: MasterZiv СССР  
Дата: 22.07.08 07:22
Оценка:
Аноним 550 пишет:

> R *pr1=new R;

> R *pr2=new(R);

placement new, если не ошибаюсь, выглядить должен примерно так:

void *some_buf = ...

R *pr2 = new (some_buf) R;
Posted via RSDN NNTP Server 2.1 beta
Re: new(R);
От: Alexander G Украина  
Дата: 22.07.08 07:56
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть ль какой то смысл в том что, данные ниже, две записи оператора new выполняют одно и тоже?

А>Что компилятор из второго варианта просто убирает скобки, или такая форма тоже правальная и эквивалентна первой?
А>Я спрашиваю это потому, что это очень похоже на оператор размещения new, может быть это он так замаскировался и размещает "ничего" в какой то постоянной области (R), в которой уже живет R.

Не похоже, т.к. в качестве параметров оператора new (как и у любого другого метода или функции) передаются значения, а не типы.
Это как sizeof(int) или sizeof int
Обычно при sizeof отделяют скобками, а при new пробелом, но это не обязательно.
Русский военный корабль идёт ко дну!
Re: new(R);
От: Roman Odaisky Украина  
Дата: 22.07.08 08:06
Оценка: 2 (1)
Здравствуйте, Аноним, Вы писали:

А>Есть ль какой то смысл в том что, данные ниже, две записи оператора new выполняют одно и тоже?

А>Что компилятор из второго варианта просто убирает скобки, или такая форма тоже правальная и эквивалентна первой?
А>Я спрашиваю это потому, что это очень похоже на оператор размещения new, может быть это он так замаскировался и размещает "ничего" в какой то постоянной области (R), в которой уже живет R.

А>
R *pr1=new R;
А>R *pr2=new(R);
А>


Это связано с грамматикой C++, которая довольно-таки запутана. Если имя типа, который предстоит создать, содержит скобки, то new сочтет их частью new-initializer. Поэтому сложные имена типов позволяется заключать в скобки. Т. е., допускается «new (тип)» или «new (тип)(аргументы инициализатора)». И «new(аргументы)(тип)(аргументы инициализатора)» тоже.

За подробностями см. 5.3.4, в частности, пример в 5.3.4/3:

[Note: parentheses in a new-type-id of a new-expression can have surprising effects. [Example:

new int(*[10])(); // error
is ill-formed because the binding is
(new int) (*[10])(); // error
Instead, the explicitly parenthesized version of the new operator can be used to create objects of compound types (3.9.2):
new (int (*[10])());
allocates an array of 10 pointers to functions (taking no argument and returning int). ] ]

До последнего не верил в пирамиду Лебедева.
Re[2]: new(R);
От: Аноним  
Дата: 22.07.08 10:02
Оценка:
Это связано с грамматикой C++, которая довольно-таки запутана. Если имя типа, который предстоит создать, содержит скобки, то new сочтет их частью new-initializer. Поэтому сложные имена типов позволяется заключать в скобки. Т. е., допускается «new (тип)» или «new (тип)(аргументы инициализатора)». И «new(аргументы)(тип)(аргументы инициализатора)» тоже.
RO>За подробностями см. 5.3.4, в частности, пример в 5.3.4/3:

А что за зверь

5.3.4/12

[Example:
— new T results in a call of operator new(sizeof(T)),
— new(2,f) T results in a call of operator new(sizeof(T),2,f),
— new T[5] results in a call of operator new[](sizeof(T)*5+x), and
— new(2,f) T[5] results in a call of operator new[](sizeof(T)*5+y,2,f).


Что означает число два? Это что размещают в размере увеличеном в/на два sizeof(T)?
Пример выделеного можно, а то нигде не нашёл.
Re[3]: new(R);
От: placement_new  
Дата: 22.07.08 10:08
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Это связано с грамматикой C++, которая довольно-таки запутана. Если имя типа, который предстоит создать, содержит скобки, то new сочтет их частью new-initializer. Поэтому сложные имена типов позволяется заключать в скобки. Т. е., допускается «new (тип)» или «new (тип)(аргументы инициализатора)». И «new(аргументы)(тип)(аргументы инициализатора)» тоже.

RO>>За подробностями см. 5.3.4, в частности, пример в 5.3.4/3:

А>А что за зверь

А>

5.3.4/12

А>[Example:
А>— new T results in a call of operator new(sizeof(T)),
А>— new(2,f) T results in a call of operator new(sizeof(T),2,f),
А>— new T[5] results in a call of operator new[](sizeof(T)*5+x), and
А>— new(2,f) T[5] results in a call of operator new[](sizeof(T)*5+y,2,f).


А>Что означает число два? Это что размещают в размере увеличеном в/на два sizeof(T)?

А>Пример выделеного можно, а то нигде не нашёл.

по моем просто вызов размещающего (по Майерсу это не только тот что адрес получает) нью определенного самим разработчиком.
Re[2]: Непонятки с placement new и локальными переменными
От: Аноним  
Дата: 22.07.08 11:10
Оценка:
Здравствуйте, Roman Odaisky.

Решил написать несколько тестов,
наткнулся на непонятное для меня поведение:
...............................................
...............................................
int *get_ptr(){
    int i = 4444;
    return &i;
}
...............................................
...............................................
    Tmp *pt4 = new(&Tmp())Tmp;
    Tmp *pt5 = 0;
    {
        Tmp tmp = {55555};
        pt5 = new(&tmp)Tmp;
    }
    int *x6 = 0;
    {
        int local_x = 88888;
        x6 = &local_x;
    }
    int *x7 = get_ptr();
    cout << "[" << pt4->x << " " << pt5->x << " "  << *x6 << " "  << *x7 << "]" << endl;
...............................................
...............................................

Выводит:
[0 55555 88888 4444]
MS VC++2005, пробовал и Debug и Release.
Я предполагал, что выводиться должен мусор, а получаю нормальные значения.
Это такая фича/бага VC++ или частый случай неопределённого поведения?
Re[2]: new(R);
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 22.07.08 11:33
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Это как sizeof(int) или sizeof int


Второй вариант некорректен.

std::size_t a = sizeof(int); // ok
std::size_t b = sizeof int;  // error
std::size_t c = sizeof(a);   // ok
std::size_t d = sizeof a;    // ok
Re[3]: new(R);
От: Alexander G Украина  
Дата: 22.07.08 11:39
Оценка:
Здравствуйте, Alxndr, Вы писали:

A>Здравствуйте, Alexander G, Вы писали:


AG>>Это как sizeof(int) или sizeof int


A>Второй вариант некорректен.


A>
A>std::size_t a = sizeof(int); // ok
A>std::size_t b = sizeof int;  // error
A>std::size_t c = sizeof(a);   // ok
A>std::size_t d = sizeof a;    // ok
A>

Да, ошибся. Попутал с int x; sizeof x.
Русский военный корабль идёт ко дну!
Re[2]: new(R);
От: Кодёнок  
Дата: 22.07.08 12:01
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>Если имя типа, который предстоит создать, содержит скобки, то new сочтет их частью new-initializer.


И строго в традициях C++ было выбрано самое нелогичное решение. Должно было быть:

new< int(*[10])() >
new< int(*[10])() >(initializer)
new<Type>(args)

// сравните с

factory_func<Type>(args)
static_cast<Type>(obj)
Re[3]: new(R);
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 22.07.08 12:06
Оценка: +2
Здравствуйте, Кодёнок, Вы писали:

Кё>И строго в традициях C++ было выбрано самое нелогичное решение. Должно было быть:


Кё>
Кё>new< int(*[10])() >
Кё>new< int(*[10])() >(initializer)
Кё>new<Type>(args)

Кё>// сравните с

Кё>factory_func<Type>(args)
Кё>static_cast<Type>(obj)
Кё>


Что-то мне подсказывает, что new был "изобретен" "немного" раньше шаблонов и соответствующей формы записи (D&E под рукой нет, не могу проверить).
Re: Продолжение new перегрузка
От: Аноним  
Дата: 22.07.08 12:21
Оценка:
Продолжение...
Насколько правильны перегрузки операторов?
Особено настораживает первый: что будет с *str после окончания видимости, не будет ли она разрушена?
void * operator new(size_t s, int i){
    char *str[sizeof(Boo)];
    Boo *bbb=reinterpret_cast<Boo*>(str);
    return bbb;

}; 
void * operator new(size_t s){
    Boo *bbb=(Boo*)malloc(s);
    return bbb;

};
Re[4]: new(R);
От: MasterZiv СССР  
Дата: 22.07.08 13:32
Оценка:
Alxndr пишет:

> Что-то мне подсказывает, что new был "изобретен" "немного" раньше

> шаблонов и соответствующей формы записи (D&E под рукой нет, не могу

Точно так.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Непонятки с placement new и локальными переменными
От: Аноним  
Дата: 22.07.08 16:13
Оценка:
Забыл написать:
class Tmp{
public:
    int x;
};
Re[3]: new(R);
От: Roman Odaisky Украина  
Дата: 22.07.08 17:35
Оценка:
Здравствуйте, Кодёнок, Вы писали:

RO>>Если имя типа, который предстоит создать, содержит скобки, то new сочтет их частью new-initializer.


Кё>И строго в традициях C++ было выбрано самое нелогичное решение. Должно было быть:


Кё>
Кё>new< int(*[10])() >
Кё>new< int(*[10])() >(initializer)
Кё>new<Type>(args)

Кё>// сравните с

Кё>factory_func<Type>(args)
Кё>static_cast<Type>(obj)
Кё>

Ну так возьми и сделай:
template <class X, class... Args>
std::unique_ptr<X> newest(Args...&& args)
{
    return std::unique_ptr<X>(new X(args...));
}

newest<int>(0);
newest<std::vector<std::string>>(42, "hello");
До последнего не верил в пирамиду Лебедева.
Re[3]: Непонятки с placement new и локальными переменными
От: Arsenicum Россия  
Дата: 23.07.08 07:08
Оценка:
Здравствуйте, Аноним, Вы писали:

...

int *get_ptr()
{
    int i = 4444;
    return &i;
}

class Tmp{
public:
    int x;
};

#include <iostream>

int main()
{
    Tmp *pt4 = new(&Tmp())Tmp;
    Tmp *pt5 = 0;
    {
        Tmp tmp = {55555};
        pt5 = new(&tmp)Tmp;
    }
    int *x6 = 0;
    {
        int local_x = 88888;
        x6 = &local_x;
    }
    int *x7 = get_ptr();
    std::cout << "[" << pt4->x << " " << pt5->x << " "  << *x6 << " "  << *x7 << "]" << std::endl;

}


Ошибки компиляции Comeau online:

"ComeauTest.c", line 4: warning: returning pointer to local variable
return &i;
^

"ComeauTest.c", line 16: error: expression must be an lvalue or a function
designator
Tmp *pt4 = new(&Tmp())Tmp;


Брр... Жуткое использование адреса локальных переменных вне области их действия. Быстренько учим матчасть!

Вас смущает, то что неопределённое поведение приводит к правильным результатам? На то оно и не определённое, что может привести к чему угоно — от правильной работы до форматирования жёсткого диска.
Re[2]: Продолжение new перегрузка
От: placement_new  
Дата: 23.07.08 07:15
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Продолжение...

А>Насколько правильны перегрузки операторов?

Про "правильную" перегрузку оператора new написано у Майерса в его первой книге.
Re[4]: Непонятки с placement new и локальными переменными
От: Аноним  
Дата: 23.07.08 18:38
Оценка:
Здравствуйте, Arsenicum, Вы писали:
A>Брр... Жуткое использование адреса локальных переменных вне области их действия. Быстренько учим матчасть!
Спасибо за наставления
A>Вас смущает, то что неопределённое поведение приводит к правильным результатам? На то оно и не определённое, что может привести к чему угоно — от правильной работы до форматирования жёсткого диска.
Да, именно это меня смущает:

Я предполагал, что выводиться должен мусор, а получаю нормальные значения.
Это такая фича/бага VC++ или частый случай неопределённого поведения?

Просто результаты получились уж очень правильные.
Можно сказать, что это — недоделка дебажного режима Студии, такое поведение скрывает глюки.
Попробовал повысить уровень предупреждений с /W3 до /W4, получил след. предупреждения:
 Tmp *pt4 = new(&Tmp())Tmp;

 warning C4238: nonstandard extension used : class rvalue used as lvalue

И в случае возврата адреса локальной переменной из функции:
warning C4172: returning address of local variable or temporary

Comeau, несомненно, гораздо более информативен.
Re[5]: Непонятки с placement new и локальными переменными
От: Arsenicum Россия  
Дата: 24.07.08 07:18
Оценка:
Здравствуйте, Аноним, Вы писали:

...

# g++ -Wall test.cpp

g++ (GCC) 4.1.2 (Gentoo 4.1.2 p1.1)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

test.cpp: In function 'int* get_ptr()':
test.cpp:3: warning: address of local variable 'i' returned
test.cpp: In function 'int main()':
test.cpp:16: warning: taking address of temporary


Я думаю комментарии о компиляторе MSVC излишни.
Re[3]: new(R);
От: shank  
Дата: 24.07.08 09:34
Оценка:
Здравствуйте, Alxndr, Вы писали:

AG>>Это как sizeof(int) или sizeof int


A>Второй вариант некорректен.


A>
A>std::size_t a = sizeof(int); // ok
A>std::size_t b = sizeof int;  // error
A>std::size_t c = sizeof(a);   // ok
A>std::size_t d = sizeof a;    // ok
A>

Кстати, VC++8.0 почему-то разрешает опускать скобки для typedef'ов.
typedef int int_type;
...
sizeof int_type; // ok
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.