реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> GCC C++ new(nothrow), как приручить?
Сергей Борщ
сообщение Apr 11 2011, 16:21
Сообщение #1


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Вроде бы по стандарту все понятно:

CODE
class myclass
{
public:
     myclass() { тра-та-та }
};

#include   <new>
void test()
{
      myclass * Tmp = new(nothrow) myclass;
      if(!Tmp)
      {
           cout < "тра-та-та не удалось";
      }

}
Но в реальности вижу, что независимо от возвращаемого new(size_t , nothrow_t) значения вызывается конструктор! А ведь new(nothrow) должен вернуть 0, если выделить память не удалось. Он и возвращает, а gcc молча вызывает конструктор с адресом объекта 0.
CODE
    known_message<decoded_message>* pElement = new(std::nothrow) known_message<decoded_message>(RSSI);
    if(pElement)
    {
  107100:    e3a0001c     mov    r0, #28
  107104:    e59f1068     ldr    r1, [pc, #104]; 107174 <decoder::received(unsigned char)+0x84>
  107108:    eb00079b     bl    108f7c <operator new(unsigned int, std::nothrow_t const&)>
    INLINE known_message(uint_fast8_t rssi) : raw_message(T::ID, sizeof(T), rssi) {}
  10710c:    e1a03007     mov    r3, r7
  107110:    e3a01002     mov    r1, #2
  107114:    e3a02008     mov    r2, #8
  107118:    e1a05000     mov    r5, r0
  10711c:    eb0002ca     bl    107c4c <raw_message::raw_message(rf_message::id, unsigned int, unsigned int)>

Что я упустил? IAR проверял и конструктор не вызывал.

P.S. Код компилируется с -fno-exceptions.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 11 2011, 18:24
Сообщение #2


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Хм. Проверил на простом gcc, для x86:

Код
class test_t
{
public:
    test_t()
    {
        std::cout << "\r\n in constructor";
    }
private:
    char arr[20];
};

void command_NTEST_handler(char*)
{
    test_t * Tmp = new(std::nothrow) test_t;
    if(!Tmp)
        std::cout << "тра-та-та не удалось";
}

скомпилилось в
Код
0000000000401220 <command_NTEST_handler(char*)>:
  401220:   48 83 ec 08             sub    $0x8,%rsp
  401224:   be f0 22 60 00          mov    $0x6022f0,%esi
  401229:   bf 14 00 00 00          mov    $0x14,%edi
  40122e:   e8 4d f9 ff ff          callq  400b80 <operator new(unsigned long, std::nothrow_t const&)@plt>
  401233:   48 85 c0                test   %rax,%rax
  401236:   74 20                   je     401258 <command_NTEST_handler(char*)+0x38>
  401238:   ba 11 00 00 00          mov    $0x11,%edx
  40123d:   be 42 18 40 00          mov    $0x401842,%esi
  401242:   bf e0 21 60 00          mov    $0x6021e0,%edi
  401247:   e8 84 f9 ff ff          callq  400bd0 <std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, st

Вроде скипается конструктор.

Потом проверил на codesourcery g++ lite:
Код
class test_t
{
public:
    test_t()
    {
        uart << "\r\n in constructor";
    }
private:
    char arr[20];
};

void command_NTEST_handler(char*)
{
    test_t * Tmp = new(std::nothrow) test_t;
    if(!Tmp)
        uart << "тра-та-та не удалось";
}

Результат:
Код
08000ff4 <command_NTEST_handler(char*)>:
8000ff4:   f641 51b0   movw    r1, #7600  ; 0x1db0
8000ff8:   b510        push    {r4, lr}
8000ffa:   2014        movs    r0, #20
8000ffc:   f6c0 0100   movt    r1, #2048  ; 0x800
8001000:   f000 f86e   bl  80010e0 <operator new(unsigned int, std::nothrow_t const&)>
8001004:   b180        cbz r0, 8001028 <command_NTEST_handler(char*)+0x34>

Опять же, вроде есть проверка...

Да, во втором случае используется нестандартный new, может это имеет значение.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 12 2011, 10:39
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (AHTOXA @ Apr 11 2011, 21:24) *
Опять же, вроде есть проверка...
Разобрался. Когда переопределял new для known_message не указал throw().


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Serega_YSV
сообщение Jan 22 2014, 09:42
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 24
Регистрация: 30-04-06
Пользователь №: 16 628



Цитата(Сергей Борщ @ Apr 12 2011, 13:39) *
Разобрался. Когда переопределял new для known_message не указал throw().

Извините, может не в тему: у меня есть проект Linux + QtGui на mips32. Для оптимизации по размеру пересобрал toolchain(gcc 4.3.6 + binutils 2.17 + eglibc-2.8) и SDK с опцией -fno-exceptions незначительно уменьшился размер libstdc++. Как по умолчанию сделать, чтобы new был std::nothrow? Toolchain не из buildroot, а самосборный с поддержкой --sysroot.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 22 2014, 11:34
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Serega_YSV @ Jan 22 2014, 11:42) *
Как по умолчанию сделать, чтобы new был std::nothrow? Toolchain не из buildroot, а самосборный с поддержкой --sysroot.

Не приходит в голову ничего кроме переопределния глобального operator new(size_t).


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Serega_YSV
сообщение Jan 22 2014, 11:36
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 24
Регистрация: 30-04-06
Пользователь №: 16 628



Цитата(Сергей Борщ @ Jan 22 2014, 14:34) *
Не приходит в голову ничего кроме переопределния глобального operator new(size_t).

Спасибо, так и сделаю.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 09:52
Рейтинг@Mail.ru


Страница сгенерированна за 0.01378 секунд с 7
ELECTRONIX ©2004-2016