Перейти к содержанию
    

GCC C++ new(nothrow)

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

 

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.

    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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хм. Проверил на простом 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, может это имеет значение.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Опять же, вроде есть проверка...
Разобрался. Когда переопределял new для known_message не указал throw().

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Разобрался. Когда переопределял 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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как по умолчанию сделать, чтобы new был std::nothrow? Toolchain не из buildroot, а самосборный с поддержкой --sysroot.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Спасибо, так и сделаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...