Silent acceptance of constraint-violating code

N

Norman Diamond

For the second time I have found Visual Studio 2005 silently accepting C++
source code that violates constraints, for which the standard requires
diagnostics.

The first case involved source code in a Microsoft publication targeting
writers of device drivers, I wondered how it could even compile, but it did
compile without a peep. Microsoft already resolved that as a "won't fix"
for the next version of Visual Studio after 2005.

Today's case involves source code not from Microsoft and not as critical as
a device driver. I'm not going to bother submitting this one for a "won't
fix". Here's a repro:

class ok_class {
public:
void ok_member(void* const & ok_param) {}
void ok_member(void*& ok_param) {}
} ok, *p_ok = &ok;

typedef void* const & ok_reference;
typedef void*& bad_reference;

int APIENTRY _tWinMain(
// .....
ok.ok_member((ok_reference) p_ok);
ok.ok_member((bad_reference) p_ok); // illegal but silently accepted
 
N

Norman Diamond

Sorry I got this one wrong.

The C-style cast (bad_reference) p_ok can be interpreted as
const_cast<bad_reference>(static_cast<good_reference>(p_ok))

I'm still trying to figure out what happens in a possible C++ implementation
where a class pointer is 4 bytes long, a void pointer is 8 bytes long, and
the called member stores a new void pointer into all 8 bytes. Bad but
legal. Argh.
 
G

Guest

For the second time I have found Visual Studio 2005 silently accepting C++
source code that violates constraints, for which the standard requires
diagnostics.

The first case involved source code in a Microsoft publication targeting
writers of device drivers, I wondered how it could even compile, but it did
compile without a peep. Microsoft already resolved that as a "won't fix"
for the next version of Visual Studio after 2005.

Out of curiosity, could you provide a link to the report you mentioned?
Btw, you don't compile device drivers with visual studio, do you?
 
T

Tom Widmer [VC++ MVP]

Norman said:
Sorry I got this one wrong.

The C-style cast (bad_reference) p_ok can be interpreted as
const_cast<bad_reference>(static_cast<good_reference>(p_ok))

I'm still trying to figure out what happens in a possible C++
implementation where a class pointer is 4 bytes long, a void pointer is
8 bytes long, and the called member stores a new void pointer into all 8
bytes. Bad but legal. Argh.

The static cast causes a temporary void pointer to be created, so the
passed pointer lvalue will not be touched, only the temporary void
pointer (whose value is lost on completion of the call).

The moral of this story is: Avoid C-style casts!

Tom
 
N

Norman Diamond

in message [Norman Diamond wrote the following lie ... though corrected it quickly ...]
For the second time I have found Visual Studio 2005 silently accepting
C++ source code that violates constraints, for which the standard
requires diagnostics.
[The following part is accurate]

The first case involved source code in a Microsoft publication targeting
writers of device drivers, I wondered how it could even compile, but it
did compile without a peep. Microsoft already resolved that as a "won't
fix" for the next version of Visual Studio after 2005.

Out of curiosity, could you provide a link to the report you mentioned?
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=98816

Btw, you don't compile device drivers with visual studio, do you?

I used scripts based on Mark Roddy's version to use the Visual Studio IDE
but invoke the DDK compilers. But that doesn't matter. The aforementioned
Microsoft publication targets device driver writers, but the particular code
in this case ran in user mode and I think it called some of the SetupDi
stuff. It still shouldn't have been allowed to compile, at least not
silently.
 
N

Norman Diamond

Tom Widmer said:
The static cast causes a temporary void pointer to be created, so the
passed pointer lvalue will not be touched, only the temporary void pointer
(whose value is lost on completion of the call).

Oh you're right, a temporary const void pointer still gets created, and the
temporary const gets its const qualification disqualified, so that thing
gets modified and yields undefined behaviour.
The moral of this story is: Avoid C-style casts!

Well, I still use them by habit, but the ones I write are less badly than
the one I read in this case.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top