Home Dashboard Directory Help
Search

Suggestions about nullptr behavior in C++/CLI code by horeaper


Status: 

Closed
 as By Design Help for as By Design


3
0
Sign in
to vote
Type: Suggestion
ID: 504788
Opened: 10/27/2009 8:56:45 PM
Access Restriction: Public
0
Workaround(s)
view

Description

The way you implements nullptr in cli is inconsistent with strings. For example, the following functions:
(The following discussion is based on cli environment, not native)

void UnmanagedFunction(const wchar_t *s);
void ManagedFunction(String ^s);

If we call them like this:

UnmanagedFunction(L"123456");
ManagedFunction(L"654321");

We both know what will happen: The L"123456" will be translated to an unmanaged wchar[], and L"654321" will be translated to managed string literal. That is, the compiler didn't assume the string as either managed or unmanaged, it translate them according to the context (in this case, the function which is used)
And if we write something like this:

void ConfuseFunction(const wchar_t *s);
void ConfuseFunction(String ^s);

Then call it:

ConfuseFunction(L"999999");

At first I assume the compiler will be confused and throw me an error, however, it's not, L"999999" will be translated to managed string literal. The only way to call the const wchar_t* one is:

ConfuseFunction((const wchar_t*)L"999999");

But for nullptr, things become different:

UnmanagedFunction(nullptr);
ManagedFunction(nullptr);

Unmanaged one will failed to compile under cli. And for the confuse one:

ConfuseFunction((const wchar_t*)nullptr);

Also will failed.
The solution it use __nullptr, !BUT!, this is a Microsoft only extension, there is no guarantee that everyone will use it. If I use someone else's open source code, like boost (I'm sure boost will handle the nullptr problem very well, but, just for example, whatever...), if they use nullptr, those "perfectly working unmanaged code" will failed to compile under cli environment, and we must change all of them to __nullptr manually. That's is something we don't what to do.

My suggestion is simple: Let the compiler translate nullptr according to the context, default to managed if confused, like what you did with strings.

(Sorry for my poor English if that's causing any trouble to you ^_^)

PS. Didn't have much time to dig into beta2. If I'm wrong, I'll be happy to know.
Details
Sign in to post a comment.
Posted by Bruno Martinez on 1/31/2012 at 6:47 AM
Add a compiler property for nullptr under /clr, similar to /Zc:wchar_t (wchar_t Is Native Type)
Posted by Microsoft on 3/20/2010 at 5:50 PM
Hi camhusmj38,

Thank you for this feedback. Currently, we recommend that developers using C++0x libraries in interop should use macros to avoid conflicts. For instance, when including a library header that utilizes C++0x nullptr into a /clr translation unit, try the following:

#define nullptr __nullptr
#include "myC++0x3rdpartylib.h"
#undef nullptr

Autodetection based on context would be very difficult given the different semantics of the managed and unmanaged nullptr, and the program may not behave as the user expected so we decided against this method. Please let me know if you have any questions.

Thanks,
Mark Roberts
Visual C++ Compiler Team
Posted by Microsoft on 10/30/2009 at 5:29 AM
Thanks for reporting this issue. We are routing this suggestion to the product unit who works on that specific feature area. The team will review this suggestion and make a decision on whether they will take it or not.

Thank you,
Visual Studio Product Team
Posted by camhusmj38 on 10/29/2009 at 5:37 AM
If you can't get the compiler to autodetect the issue, I would rather _nullptr meant unmanaged (i.e. break C++/CLI before you break C++0x.) This would allow me to use existing unmanaged libraries in interop without rewriting them. I can rewrite my interop code more easily as there is less of it.
Posted by camhusmj38 on 10/29/2009 at 5:33 AM
Yes, it would be better if the compiler could detect whether you meant managed or unmanaged nullptr rather than use the _nullptr keyword. Even if there were corner cases where this could not be done, I think it would work in typical cases (e.g.

Object^ x = nullptr; // I must mean managed as using ^
int * xx = nullptr; // I must mean unmanaged as using int*.

)
Sign in to post a workaround.