vc++ compiler bug or fixable error?

Started by
5 comments, last by Koen 16 years ago
I have compiled the following code in Visual C++ Express 9.0.21022.8. I use Warning Level 4 and I have C++ exceptions enabled (/EHsc)

void ThrowingFunction()
  {
  throw SomeException();
  }

int OtherFunction()
  {
  ThrowingFunction();
  return 0; //C4702
  }

In release the code generates warning "C4702 unreachable code" for the return statement. If I remove that line, I get a warning in debug ("C4715 not all control paths return a value"). Since I'm treating warnings as errors, this is a problem :) I can see why the 'unreachable code' warning is triggered: if the compiler inlines ThrowingFunction the result would be

int OtherFunction()
  {
  throw SomeException();
  return 0; //C4702
  }

But I don't think the result of optimisations should be my problem... Or am I missing something here? The above example is obviously a simplification. Here is my actual code:

void ThrowFailedAPICallException(const TString& i_message_base)
  {
  TString error_message = i_message_base + L": " + GetLastErrorMessage();
  throw FailedAPICallException(error_message);
  }

AutoHandle OpenProcessToken()
  {
  HANDLE h_token;

  if (OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &h_token) == TRUE)
    return AutoHandle(h_token);
    
  ThrowFailedAPICallException(L"Failed to open process token");

  return AutoHandle();
  }

Advertisement
Declare your throwing function as __declspec(noreturn), and that should tell the compiler not to expect any code after the function call to be executed.
Yup, that fixes the error. Thanks! I've googled the noreturn thingy, and it seems that even if it is not according to the c++ standard, MS will not likely fix it: Visual C++ Team Blog: Bug Submission Guidelines. In the last paragraph of that post, it says
Quote:
If any of the following applies, we will not consider a fix for the bug:
· A reasonable workaround exists

I guess using __declspec(noreturn) is a reasonable workaround.
Still don't like it though...
You could just disable C4702 or C4715 instead.
I just thought of a workaround:
AutoHandle OpenProcessToken()  {  HANDLE h_token;  if (OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &h_token) == FALSE)    ThrowFailedAPICallException(L"Failed to open process token");    return AutoHandle(h_token);  }

This is even better: no declspec needed, and less lines of code [grin]
If I infer correctly, are you trying for open-source? You could do something like this to keep your portability:

#ifdef _MSC_VER#	define SPEC_NORETURN	__declspec( noreturn )#else#	define SPEC_NORETURN	#endifvoid SPEC_NORETURN ThrowingFunction(){	/* ... */}
Quote:Original post by _fastcall
If I infer correctly, are you trying for open-source?

No, not at all. I was writing a small tool for my own use. I simply prefer to not use compiler specific constructs in my code.
But thanks anyway for the suggestion!

This topic is closed to new replies.

Advertisement