Jump to content

    

Recommended Posts

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

 

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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
Разобрался. Когда переопределял 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.

Share this post


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

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this