void () и new
От: Аноним  
Дата: 28.02.12 12:47
Оценка:
Приветствую.

— Скажите, пожалуйста, а вот такое в C++ по стандарту?

void f ()
{
    return void ();
}


А вот такое?

void f () {}

void g ()
{
    return g ();
}


Если да, то с какого момента?

И как вообще читать запись void ()?

Вызов конструктора void? Так ведь у встроенных типов нет конструкторов.

— Допустим, у нас имеется такой код:

String *newString = new String ("str");


Если оператор new отработал некорректно, то вызов

delete newString;


вызовет UB, ведь так?
Re: void () и new
От: Сыроежка  
Дата: 28.02.12 12:58
Оценка: +1 -4
Здравствуйте, Аноним, Вы писали:

А>Приветствую.


А>- Скажите, пожалуйста, а вот такое в C++ по стандарту?


А>
А>void f ()
А>{
А>    return void ();
А>}
А>


Это не соответствует сттандарту, так как функция, имеющая тип возвращаемого значения void не должна содержать предложение return, содержащее выражение.


А>А вот такое?


А>
А>void f () {}

А>void g ()
А>{
А>    return g ();
А>}
А>


Здесь тоже самое несоответствие стандарту, так как после return стоит выражение.

А>Если да, то с какого момента?


А>И как вообще читать запись void ()?


А>Вызов конструктора void? Так ведь у встроенных типов нет конструкторов.


Это читается как тип функции, возвращающей void и не имеющей параметров.


А>- Допустим, у нас имеется такой код:


А>
А>String *newString = new String ("str");
А>


А>Если оператор new отработал некорректно, то вызов


А>
А>delete newString;
А>


А>вызовет UB, ведь так?


Если оператор new отработал некорректно, то оон сгенерирует исключение. Поэтому действительно вызов затем delete newString; является неопредленным поведением, если до этого вы не присвоили этому указателю нулевое константное значение.
Ежели вы установили, что new не будет генерировать исключение, а будет возвращаьб нулевое значение, как это принято в С в случае неуспеха, то в этом случае вызов delete будет корректным, так как вы вызовите этот оператор для нуллевого туказателя.
Меня можно встретить на www.cpp.forum24.ru
Re[2]: void () и new
От: Сыроежка  
Дата: 28.02.12 13:04
Оценка: -1
Здравствуйте, Сыроежка, Вы писали:

С>Здравствуйте, Аноним, Вы писали:


А>>Приветствую.


А>>- Скажите, пожалуйста, а вот такое в C++ по стандарту?


А>>
А>>void f ()
А>>{
А>>    return void ();
А>>}
А>>


С>Это не соответствует сттандарту, так как функция, имеющая тип возвращаемого значения void не должна содержать предложение return, содержащее выражение. Кроме того это вообще должно выдать ошибку компиляции, так как вы не указали объект, а лишь пытаетесь вернуть тип объекта.
Меня можно встретить на www.cpp.forum24.ru
Re[2]: void () и new
От: YourLastSong  
Дата: 28.02.12 13:06
Оценка:
С>Это не соответствует сттандарту, так как функция, имеющая тип возвращаемого значения void не должна содержать предложение return, содержащее выражение.

Странно, потому что как Visual Studio, так и gcc абсолютно корретно отрабатывают данный код.

Ни Visual Studio, ни gcc ничего не сказали.
Re: void () и new
От: llex  
Дата: 28.02.12 13:18
Оценка: -1
Здравствуйте, Аноним, Вы писали:

А>Приветствую.


А>- Скажите, пожалуйста, а вот такое в C++ по стандарту?


А>
А>void f ()
А>{
А>    return void ();
А>}
А>


А>И как вообще читать запись void ()?

А>Вызов конструктора void? Так ведь у встроенных типов нет конструкторов.

Точно сказать, что это не могу, но для встроенных типов запись вида
"TYPE()" должна приравнивается к "(TYPE)", т.е. приведение типа.

-----------------------------------------------------
А>А вот такое?

А>
А>void f () {}

А>void g ()
А>{
А>    return g ();
А>}
А>


Это по стандарту: функция "возвращающая void" может возвращать "функцию, возвращающую void".
Это используется при написании шаблонов.
Re: void () и new
От: k.o. Россия  
Дата: 28.02.12 13:23
Оценка: 12 (5)
Здравствуйте, Аноним, Вы писали:

А>Приветствую.


А>- Скажите, пожалуйста, а вот такое в C++ по стандарту?


Да

5.2.3/2

The expression T(), where T is a simple-type-specifier or typename-specifier for a non-array complete object
type or the (possibly cv-qualified) void type, creates a prvalue of the specified type, which is value-initialized
(8.5; no initialization is done for the void() case).


и 6.6.3/3

A return statement with an expression of type “cv void” can be used only in functions with a return type
of cv void; the expression is evaluated just before the function returns to its caller.


А>Если да, то с какого момента?


По крайней, мере, начиная со стандарта 1998 года, т.е. это всегда так (по-стандарту) было.

А>И как вообще читать запись void ()?


А>Вызов конструктора void? Так ведь у встроенных типов нет конструкторов.


Это не вызов конструктора, а value-initialization (default-initialization в стандартах 1998 и 2003 г), для встроенных типов это инициализация 0-ми. Для void, как видно из цитаты никакой инициализации не происходит, просто получаем prvalue/rvalue.
Re[2]: void () и new
От: watch-maker  
Дата: 28.02.12 13:24
Оценка: 3 (1) +3
Здравствуйте, Сыроежка, Вы писали:

С>Это не соответствует сттандарту, так как функция, имеющая тип возвращаемого значения void не должна содержать предложение return, содержащее выражение.


С>Здесь тоже самое несоответствие стандарту, так как после return стоит выражение.


Глупости. Всё законно:

6.3.3 3
A return statement with an expression of type “cv void” can be used only in functions with a return type
of cv void; the expression is evaluated just before the function returns to its caller.

Re[3]: void () и new
От: Сыроежка  
Дата: 28.02.12 13:31
Оценка:
Здравствуйте, YourLastSong, Вы писали:

С>>Это не соответствует сттандарту, так как функция, имеющая тип возвращаемого значения void не должна содержать предложение return, содержащее выражение.


YLS>Странно, потому что как Visual Studio, так и gcc абсолютно корретно отрабатывают данный код.


YLS>Ни Visual Studio, ни gcc ничего не сказали.


Я не совсем точно выразился. Еа самом деле выражение типа void может присутствовать в предложение return для функуции, возвращающей void. Не может присутствовать выражение, не имеющее тип void

В приведеннном примере имеет место

return void ();

Что такое void ()? На мой взгляд как выражение оно некорреткно. Что здесь первичное выражение? мы имеем пустые круглые скобки. Это напоминает задание типа функции. Но это же не имеет отношение к выражению. Поэтому мне представляется, что должна быть ощшибка компиляции. Или же здесь имеет место такая синтаксическая конструкция, которую я не вижу.
Меня можно встретить на www.cpp.forum24.ru
Re[3]: void () и new
От: Сыроежка  
Дата: 28.02.12 13:33
Оценка:
Здравствуйте, watch-maker, Вы писали:

WM>Здравствуйте, Сыроежка, Вы писали:


С>>Это не соответствует сттандарту, так как функция, имеющая тип возвращаемого значения void не должна содержать предложение return, содержащее выражение.


С>>Здесь тоже самое несоответствие стандарту, так как после return стоит выражение.


WM>Глупости. Всё законно:


WM>

WM>6.3.3 3
WM>A return statement with an expression of type “cv void” can be used only in functions with a return type
WM>of cv void; the expression is evaluated just before the function returns to its caller.



Я уже выше поправился. Проблема в том, что я не вижу в возвращаепмом значении примера выражение типа void.
Меня можно встретить на www.cpp.forum24.ru
Re[2]: void () и new
От: Сыроежка  
Дата: 28.02.12 13:38
Оценка: +1
Здравствуйте, k.o., Вы писали:

KO>Здравствуйте, Аноним, Вы писали:


А>>Приветствую.


А>>- Скажите, пожалуйста, а вот такое в C++ по стандарту?


KO>Да


KO>5.2.3/2


KO>

KO>The expression T(), where T is a simple-type-specifier or typename-specifier for a non-array complete object
KO>type or the (possibly cv-qualified) void type, creates a prvalue of the specified type, which is value-initialized
KO>(8.5; no initialization is done for the void() case).


Я как-то раньше на это не разбирался в этих деталях, так как не было необходимости. Тепероь буду знать, что void() — это корректная конструкция.
Я так думаю, что это сделали из-за шаблонов, так как заранее неизвестно, какой тип будет использован в качестве аргумента, а потому чтобы не возникало ошибки компиляции при инстанировании шаблона, когда используется void разрешили такую конструкцию.
Меня можно встретить на www.cpp.forum24.ru
Re: void () и new
От: fuyant  
Дата: 28.02.12 14:14
Оценка:
Здравствуйте, Аноним, Вы писали:

А>
А>void f ()
А>{
А>    return void ();
А>}
А>


можно даже так:

void SetErr (int & err)
{
    err = 15;
}

void GetErr (int & err)
{
    return SetErr (err);
}

int main (int, char **)
{
    int e = 0;
    GetErr (e);
    printf ("%d", e);
}
Re[2]: void () и new
От: Vlad_SP  
Дата: 29.02.12 06:29
Оценка:
Здравствуйте, Сыроежка, Вы писали:

А>>
А>>String *newString = new String ("str");
А>>delete newString;
А>>

С>Если оператор new отработал некорректно, то он сгенерирует исключение. Поэтому действительно вызов затем delete newString; является неопределенным поведением, если до этого вы не присвоили этому указателю нулевое константное значение.

Если оператор new в этом коде выбросит исключение, до выполнения delete newString дело даже не дойдет. Так что неопределенного поведения не будет.
Re[2]: void () и new
От: о_О
Дата: 29.02.12 06:37
Оценка:
Здравствуйте, llex, Вы писали:

L>Точно сказать, что это не могу, но для встроенных типов запись вида

L>"TYPE()" должна приравнивается к "(TYPE)", т.е. приведение типа.

с чего вдруг?

5.2.3/2
The expression T(), where T is a simple-type-specifier or typename-specifier for a non-array complete object
type or the (possibly cv-qualified) void type, creates a prvalue of the specified type, which is value-initialized
(8.5; no initialization is done for the void() case).

Re[3]: void () и new
От: о_О
Дата: 29.02.12 07:39
Оценка:
Здравствуйте, YourLastSong, Вы писали:

купи уже себе нормальную книгу. глупых вопросов не будет чуть более чем полностью
Re[3]: void () и new
От: Сыроежка  
Дата: 29.02.12 08:11
Оценка:
Здравствуйте, Vlad_SP, Вы писали:

V_S>Здравствуйте, Сыроежка, Вы писали:


А>>>
А>>>String *newString = new String ("str");
А>>>delete newString;
А>>>

С>>Если оператор new отработал некорректно, то он сгенерирует исключение. Поэтому действительно вызов затем delete newString; является неопределенным поведением, если до этого вы не присвоили этому указателю нулевое константное значение.

V_S>Если оператор new в этом коде выбросит исключение, до выполнения delete newString дело даже не дойдет. Так что неопределенного поведения не будет.


Вопрос о том, что программист сам может вызвать delete, а не о том, что компилятор будет делать delete.
Меня можно встретить на www.cpp.forum24.ru
Re[4]: void () и new
От: Vlad_SP  
Дата: 29.02.12 08:25
Оценка:
Здравствуйте, Сыроежка, Вы писали:

дык, в этом коде программист именно сам вызывает delete. И тем не менее, неопределенного поведения нет.
Re[5]: void () и new
От: Сыроежка  
Дата: 29.02.12 09:25
Оценка:
Здравствуйте, Vlad_SP, Вы писали:

V_S>Здравствуйте, Сыроежка, Вы писали:


V_S>дык, в этом коде программист именно сам вызывает delete. И тем не менее, неопределенного поведения нет.


Причем здесь этот код?! Это условный пример, демонстрирующий наличие вызовов. Предложение с delete может стоять в любом месте. Вопрос стоит о том, можно ли вызывать delete или нет, и к каким последствиям это приведет.
Меня можно встретить на www.cpp.forum24.ru
Re[6]: void () и new
От: Vlad_SP  
Дата: 29.02.12 10:00
Оценка:
Здравствуйте, Сыроежка, Вы писали:

вернемся к исходному вопросу:

— Допустим, у нас имеется такой код:
String *newString = new String ("str");
Если оператор new отработал некорректно, то вызов
delete newString;
вызовет UB, ведь так?


Это предположение ТС неверно. UB не будет.
Re[7]: void () и new
От: Сыроежка  
Дата: 29.02.12 10:37
Оценка:
Здравствуйте, Vlad_SP, Вы писали:

V_S>Здравствуйте, Сыроежка, Вы писали:


V_S>вернемся к исходному вопросу:

V_S>

— Допустим, у нас имеется такой код:
V_S>String *newString = new String ("str");
V_S>Если оператор new отработал некорректно, то вызов
V_S>delete newString;
V_S>вызовет UB, ведь так?


V_S>Это предположение ТС неверно. UB не будет.


Почему же не верно?


String *newString;

try
{
   newString = new String( "str" );
}
catch ( ... )
{
   delete newString;
}


Что же будет по вашему при вызове delete?
Меня можно встретить на www.cpp.forum24.ru
Re[8]: void () и new
От: Vlad_SP  
Дата: 29.02.12 11:00
Оценка:
Здравствуйте, Сыроежка,

Сравни:
    String *newString = new String ("str");

    delete newString;

и
    String *newString;
    try
    {
       newString = new String( "str" );
    }
    catch ( ... )
    {
       delete newString;
    }


Ты действительно не видишь разницы в коде?
Разумеется, во втором варианте будет UB. Но это — твой вариант кода, а не тот код, о котором спрашивал TC; и давай не будем домысливать за топикстартера варианты (сферического) кода (в вакууме). ТС спросил о конкретном коде (и привел этот код), порождает ли он UB. Ответ — нет. Если ты считаешь иначе — попробуй в варианте ТС (до/на)писать код, порождающий UB — конечно же, без нечестных приемов вида
String *newString = new String ("str");
newString = (String*)0x12345678;
delete newString;
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.