Кто опять неправ?
От: BitField Украина http://lazy-bitfield.blogspot.com
Дата: 29.11.05 12:17
Оценка: 5 (1)
Друг начал учить С++. Посмотрев на одну из его программ, я надолго впал в ступор....
Вот вырезка:
int main(int argc, char * argv[])
{
  char * text = new char [20] = "Hello world";
  printf("%s", text);
  return 0;
}

msvc ТАКОЕ спокойно компилит, даже без ворнингов.
gcc послал.
Re: Кто опять неправ?
От: Vamp Россия  
Дата: 29.11.05 12:20
Оценка:
BF>msvc ТАКОЕ спокойно компилит, даже без ворнингов.
Странно. new char[20] возвращает rvalue. А какая версия?
Да здравствует мыло душистое и веревка пушистая.
Re: Кто опять неправ?
От: Bell Россия  
Дата: 29.11.05 12:20
Оценка:
Здравствуйте, BitField, Вы писали:

BF>Друг начал учить С++. Посмотрев на одну из его программ, я надолго впал в ступор....

BF>Вот вырезка:
BF>
BF>int main(int argc, char * argv[])
BF>{
BF>  char * text = new char [20] = "Hello world";
BF>  printf("%s", text);
BF>  return 0;
BF>}
BF>

BF>msvc ТАКОЕ спокойно компилит, даже без ворнингов.
BF>gcc послал.

А что сказал gcc?
В принципе, стандарт допускает преобразование строкового литерала в char*.

ЗЫ
Про утечку говорить ведь не нужно?
Любите книгу — источник знаний (с) М.Горький
Re[2]: Кто опять неправ?
От: Глеб Алексеев  
Дата: 29.11.05 12:21
Оценка:
Здравствуйте, Vamp, Вы писали:

BF>>msvc ТАКОЕ спокойно компилит, даже без ворнингов.

V>Странно. new char[20] возвращает rvalue. А какая версия?
2003-я .
Надо бы на 2005-й проверить.
... << RSDN@Home 1.2.0 alpha rev. 619>>
Re[2]: Кто опять неправ?
От: Глеб Алексеев  
Дата: 29.11.05 12:24
Оценка: 1 (1)
Здравствуйте, Bell, Вы писали:

B>А что сказал gcc?

Comeau сказал
"ComeauTest.c", line 4: error: expression must be a modifiable lvalue
    char * text = new char [20] = "Hello world";
                  ^

B>В принципе, стандарт допускает преобразование строкового литерала в char*.
А разве (new char [20]) — это lvalue?
... << RSDN@Home 1.2.0 alpha rev. 619>>
Re: Кто опять неправ?
От: andrij Украина  
Дата: 29.11.05 12:27
Оценка:
On Tue, 29 Nov 2005 14:17:06 +0200, BitField <16909@users.rsdn.ru> wrote:

> Друг начал учить С++. Посмотрев на одну из его программ, я надолго впал в ступор....

> Вот вырезка:
>
> int main(int argc, char * argv[])
> {
>   char * text = new char [20] = "Hello world";
>   printf("%s", text);
>   return 0;
> }
>

> msvc ТАКОЕ спокойно компилит, даже без ворнингов.
> gcc послал.

gcc таки послал — сказал што нельзя присваивать значения непеременними:
(я сним согласен )

main.cpp:9: error: ISO C++ forbids cast to non-reference type used as lvalue
main.cpp:9: error: ISO C++ forbids cast to non-reference type used as lvalue


7.1 — сожрал и даже виполнил видав нагора "Hello world", вот уж действительно:
"Hello world" !!!
— помоему просто баг.

если ктото проверит в 2005-й — дайте знать.
Posted via RSDN NNTP Server 1.9
make it simple as possible, but not simpler
Re[3]: Кто опять неправ?
От: Bell Россия  
Дата: 29.11.05 12:27
Оценка:
Здравствуйте, Глеб Алексеев, Вы писали:

ГА>А разве (new char [20]) — это lvalue?

Да нет конечно
Любите книгу — источник знаний (с) М.Горький
Re[2]: Кто опять неправ?
От: avbochagov Россия  
Дата: 29.11.05 12:51
Оценка: 1 (1) +1
Здравствуйте, andrij, Вы писали:

A>если ктото проверит в 2005-й — дайте знать.


2005 релиз нормально откомпилил и выполнил
... << RSDN@Home 1.2.0 alpha rev. 621>>
Re: Кто опять неправ?
От: _Winnie Россия C++.freerun
Дата: 29.11.05 15:25
Оценка:
Невероятно, но факт. new char[] — L-VALUE.
void f(char **p)
{
}

int main(int argc, char * argv[])
{
    f(&(new char [20]));
    return 0;
}


в VS2005 та же ботва, даже с ключем /Za.
Правильно работающая программа — просто частный случай Undefined Behavior
Re[2]: Кто опять неправ?
От: Глеб Алексеев  
Дата: 29.11.05 15:29
Оценка: :)
Здравствуйте, _Winnie, Вы писали:

_W>Невероятно, но факт. new char[] — L-VALUE.

_W>
_W>void f(char **p)
_W>{
_W>}

_W>int main(int argc, char * argv[])
_W>{
_W>    f(&(new char [20]));
_W>    return 0;
_W>}
_W>


_W>в VS2005 та же ботва, даже с ключем /Za.

Похоже на то, что большинство глюков VS2003 прекрасно себя чувствуют в VS2005.
"ComeauTest.c", line 7: error: expression must be an lvalue or a function designator
      f(&(new char [20]));
... << RSDN@Home 1.2.0 alpha rev. 619>>
Re[3]: Кто опять неправ?
От: srggal Украина  
Дата: 29.11.05 15:44
Оценка: :))) :)))
Здравствуйте, Глеб Алексеев, Вы писали:

ГА>Похоже на то, что большинство глюков VS2003 прекрасно себя чувствуют в VS2005.

ГА>
ГА>"ComeauTest.c", line 7: error: expression must be an lvalue or a function designator
ГА>      f(&(new char [20]));
ГА>


Обратная совместимость
... << RSDN@Home 1.1.4 stable rev. 510>>
Re: Кто опять неправ?
От: gear nuke  
Дата: 30.11.05 15:45
Оценка:
Здравствуйте, BitField, Вы писали:

BF>Друг начал учить С++. Посмотрев на одну из его программ, я надолго впал в ступор....

BF>Вот вырезка:
BF>
BF>int main(int argc, char * argv[])
BF>{
BF>  char * volatile text = new char [20] = "Hello world";
BF>  printf("%s", text);
BF>  return 0;
BF>}

BF>msvc ТАКОЕ спокойно компилит, даже без ворнингов.

Немного модифицировал, что бы понять, что происходит.

$SG3747 DB  'Hello world', 00H
$SG3748 DB  '%s', 00H

_main   PROC
    ; выдел место в стеке под переменную text  
    push    ecx

    ; new char [20];
    ; указатель на выделенную память нигде не сохраняется!
    push    20                  ; 00000014H
    call    ??2@YAPAXI@Z        ; operator new

    ; char * volatile text = "Hello world";
    mov DWORD PTR _text$[esp+8], OFFSET $SG3747
        
    ; printf("%s", text);
    mov eax, DWORD PTR _text$[esp+8]
    push    eax
    push    OFFSET $SG3748
    call    _printf
        
    ; return 0;
    xor eax, eax
    add esp, 16
    ret 0
_main   ENDP

Так что new всё-таки не lvalue. Каким таким чудом компилятор выполнил присваивание "вокруг него"
Подобный баг наводит на мысль — что этот пример ещё цветочки. Сколько может быть таких вещей в "работающих" программах?
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[2]: Кто опять неправ?
От: _Winnie Россия C++.freerun
Дата: 30.11.05 16:58
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, BitField, Вы писали:



GN>Немного модифицировал, что бы понять, что происходит.

GN>Так что new всё-таки не lvalue. Каким таким чудом компилятор выполнил присваивание "вокруг него"
GN>Подобный баг наводит на мысль — что этот пример ещё цветочки. Сколько может быть таких вещей в "работающих" программах?

>; указатель на выделенную память нигде не сохраняется!

Ну да.
А зачем?
Поставим скобки согласно правилам С++:
 char * volatile text = (new char [20] = "Hello world");

>Так что new всё-таки не lvalue.
Почему такой вывод?
Правильно работающая программа — просто частный случай Undefined Behavior
Re[3]: Кто опять неправ?
От: gear nuke  
Дата: 30.11.05 17:23
Оценка:
Здравствуйте, _Winnie, Вы писали:

>>; указатель на выделенную память нигде не сохраняется!

_W>Ну да.
_W>А зачем?

А зачем тогда оптимизатор не выкинул выделение памяти?
Результат не сохраняется — имеет право. Но не сделал.

_W>Поставим скобки согласно правилам С++:

_W>
_W> char * volatile text = (new char [20] = "Hello world");

Поведение компилятора не меняется.

>>Так что new всё-таки не lvalue.

_W>Почему такой вывод?

Мой вывод такой:
после некоторых преобразований, выражение приводится компилятором к виду:
new char [20];
char * volatile text = "Hello world";

Компилятор не рассматирвает new как lvalue в таком контексте.
Он его из контекста выкидывает!
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[4]: Кто опять неправ?
От: Centaur Россия  
Дата: 01.12.05 17:11
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, _Winnie, Вы писали:


>>>; указатель на выделенную память нигде не сохраняется!

_W>>Ну да.
_W>>А зачем?

GN>А зачем тогда оптимизатор не выкинул выделение памяти?

GN>Результат не сохраняется — имеет право. Но не сделал.

Не имеет. Выражение new вызывает (рано или поздно, прямо или косвенно) библиотечную функцию (operator new, malloc или платформозависимый эквивалент), а это observable behavior (1.9/6).
Re[5]: Кто опять неправ?
От: gear nuke  
Дата: 01.12.05 17:35
Оценка: +1
Здравствуйте, Centaur,

GN>>А зачем тогда оптимизатор не выкинул выделение памяти?

GN>>Результат не сохраняется — имеет право. Но не сделал.

C>Не имеет. Выражение new вызывает (рано или поздно, прямо или косвенно) библиотечную функцию (operator new, malloc или платформозависимый эквивалент), а это observable behavior (1.9/6).


The observable behavior of the abstract machine is its sequence of reads and writes to volatile data and
calls to library I/O functions.


А operator new — это I/O функция?
Если да, то почему тогда выделение памяти под auto переменные не является observable behavior?
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.