2

Possible Duplicate:
Public operator new, private operator delete: getting C2248 “can not access private member” when using new

http://efesx.com/2009/12/01/public-operator-new-and-private-operator-delete/

In this article i read that this code should give an error:

#include <cstdlib>

struct Try {
        Try () { /* o/ */ }

        void *operator new (size_t size) {
            return malloc(size);
        }

    private:
        void operator delete (void *obj) {
            free(obj);
        }
};

int main () {
    Try *t = new Try();

    return 0;
}

I tried it with gcc 4.7.1:

Compilation finished with errors: source.cpp: In function 'int
main()': source.cpp:11:14: error: 'static void Try::operator
delete(void*)' is private source.cpp:17:22: error: within this context
source.cpp:11:14: error: 'static void Try::operator delete(void*)' is
private source.cpp:17:22: error: within this context source.cpp:17:10:
warning: unused variable 't' [-Wunused-variable]

In comment in this article i saw this link - Public operator new, private operator delete: getting C2248 "can not access private member" when using new

If i unserstand it correct, it doesn't compile because compiler should avoid any memory leaks in situations when there are exception thrown from constructor by calling the appropriate operator delete. But why this code compile and works?

#include <cstdlib>

struct Try {
        void *operator new (size_t size) {
            return malloc(size);
        }

    private:
        void operator delete (void *obj) {
            free(obj);
        }
};

int main () {
    Try *t = new Try;

    return 0;
}

Is it correct by standard or not?

And what about this code?

#include <cstdlib>

struct Try {
        void *operator new (size_t size) {
            return malloc(size);
        }

    private:
        void operator delete (void *obj) {
            free(obj);
        }
};

int main () {
    Try *t = new Try();

    return 0;
}

It doesn't compile with gcc 4.7.1.

And how things like this should be implemented in the standard library?

Comeau doesn't compile all these examples:

"ComeauTest.c", line 15: error: function "Try::operator delete"
(declared at line 9) is inaccessible Try *t = new Try; ^

Can anyone explain me this in detail, please?

Community
  • 1
  • 1
FrozenHeart
  • 19,844
  • 33
  • 126
  • 242
  • The answer is linked to in the comments section of the link you have at the top your question. I linked that question as a duplicate of your question. – Tony The Lion Sep 21 '12 at 18:40
  • Are you asking why the first and third examples don't compile, or why the second (using `new Try` rather than `new Try()`) does? The "duplicate" only answers the first of those. – Mike Seymour Sep 21 '12 at 18:47
  • I want to know why different compilers works in different ways – FrozenHeart Sep 21 '12 at 19:36

2 Answers2

2
  • Seems, you are right about the first example.

Second and third examples deal with POD type. And there initialization differences play role.

  • In the second example your structure left uninitialized. No problem appear.

  • In opposite, in third example structure does initialize, so you get first case.

Edit:

Then, operator new itself can throw an exception. Standard (c++11 darft says):

If the new expression terminates by throwing an exception, it may release storage by calling a deallocation function (3.7.4.2). If the allocated type is a non-array type, the allocation function’s name is operator new and the deallocation function’s name is operator delete.

It's bit unclear, what authors wanted to express saying it may release storage. It seems to be implementation defined, if it is released.

Anyway, you can try using not-throwing new version:

void *operator new (size_t size, std::nothrow_t) throw() {
    return malloc(size);
}
Community
  • 1
  • 1
Lol4t0
  • 12,444
  • 4
  • 29
  • 65
0

Compiler creating constructor code which involves operators new and delete too in case if your constructor code throws an exception. So, using new automatically creates usage of delete.

In 2nd example compiler knows you using default constructor which never throws(my guess)..

Different compilers work different ways cus they are different (captain) and have different optimization capabilities and tricks to create code

Galimov Albert
  • 7,269
  • 1
  • 24
  • 50