is it possible to programmatically detect Visual C++ 2005 SP1?

  • Thread starter Thread starter Jonathan Wilson
  • Start date Start date
J

Jonathan Wilson

Is there some way I can do something like this
#if <running on Visual C++ 2005 SP1>
//SP1 code here
#else
//other code here
#endif
 
Hi Jonathan!
Is there some way I can do something like this
#if <running on Visual C++ 2005 SP1>
//SP1 code here
#else
//other code here
#endif

Currently I don't see a way...
But: Why do nou need it?

Greetings
Jochen
 
Microsoft has made some changes to the CxxUnhandledExceptionFilter logic in
Visual C++ 2005 SP1. Because of the way that my code (in a dll) is linked
to executable files compiled with Visual C++ 6 (and that I cant touch),
this change has broken my functionality that I have for dumping debug
information in the event of a crash. I have a workaround that makes it work
again with VS2005 SP1 but that only works on VS2005 SP1 and not on VS2005.
Hence the need to detect the difference :)
 
Microsoft has made some changes to the CxxUnhandledExceptionFilter logic
in Visual C++ 2005 SP1. Because of the way that my code (in a dll) is
linked to executable files compiled with Visual C++ 6 (and that I cant
touch), this change has broken my functionality that I have for dumping
debug information in the event of a crash. I have a workaround that makes
it work again with VS2005 SP1 but that only works on VS2005 SP1 and not on
VS2005. Hence the need to detect the difference :)

Hi,

I think I have found a way to do this at runtime, not compile time.
Basically, I looked in the list of resolved bugs to find anything simple
that could differentiate between RTM and SP1.
http://blogs.msdn.com/vcblog/archive/2006/06/22/643325.aspx

I picked out this one:
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101702

And made the following example:
char test[10];
if (sizeof(&test)==4)
cout << "SP1";
else
cout << "RTM";

With RTM, the sizeof is 10 instead of 4, so RTM is printed.
I would have tested it with SP1 before posting my reply here, but it is
still being installed. apparently, this can take a long, long time.
A quick test should provide you with the answer.
Combine my example with _MSC_VER and you can exactly see which version you
have compiled your app with.

I just used this bugfix to differentiate, but maybe if you search through
the complete list you may find something that can differentiate at compile
time.
Hope this helps. Let me know.

--

Kind regards,
Bruno van Dooren
(e-mail address removed)
Remove only "_nos_pam"
 
Bruno van Dooren said:
Microsoft has made some changes to the CxxUnhandledExceptionFilter logic
in Visual C++ 2005 SP1. Because of the way that my code (in a dll) is
linked to executable files compiled with Visual C++ 6 (and that I cant
touch), this change has broken my functionality that I have for dumping
debug information in the event of a crash. I have a workaround that makes
it work again with VS2005 SP1 but that only works on VS2005 SP1 and not
on VS2005. Hence the need to detect the difference :)

Hi,

I think I have found a way to do this at runtime, not compile time.
Basically, I looked in the list of resolved bugs to find anything simple
that could differentiate between RTM and SP1.
http://blogs.msdn.com/vcblog/archive/2006/06/22/643325.aspx

I picked out this one:
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101702

And made the following example:
char test[10];
if (sizeof(&test)==4)
cout << "SP1";
else
cout << "RTM";

With RTM, the sizeof is 10 instead of 4, so RTM is printed.
I would have tested it with SP1 before posting my reply here, but it is
still being installed. apparently, this can take a long, long time.
A quick test should provide you with the answer.
Combine my example with _MSC_VER and you can exactly see which version you
have compiled your app with.

I just used this bugfix to differentiate, but maybe if you search through
the complete list you may find something that can differentiate at compile
time.

Since sizeof is a compile-time operator, that should be usable with
templates to select different code paths at compile time.

It won't look quite the same as preprocessor conditionals though.
 
Hi Jonathan!
Is there some way I can do something like this
#if <running on Visual C++ 2005 SP1>
//SP1 code here
#else
//other code here
#endif

Yu could use the "_CRT_ASSEMBLY_VERSION" define...
But this only works if you do *not* define "_USE_RTM_VERSION"...

if (strcmp(_CRT_ASSEMBLY_VERSION, "8.0.50727.762") == 0)
_tprintf(_T("SP1\n"));
else
_tprintf(_T("RTM\n"));

Greetings
Jochen
 
Since sizeof is a compile-time operator, that should be usable with
templates to select different code paths at compile time.

Thanks to Ben who gave me the idea, I have created a compile time solution:

template <int i> class VcSelectorClass
{
public:
static char Dummy[10];
static void DoStuff(void)
{
//put code for VC2005 RTM here
cout << "RTM" << endl;
}
};

template <> class VcSelectorClass<4>
{
public:
static void DoStuff(void)
{
//put code for VC2005 SP1 here
cout << "SP1" << endl;
}
};
//typedef for making things automatic without forcing you to type too much
garbage
typedef VcSelectorClass<sizeof(&VcSelectorClass<0>::Dummy)> VcSelector;

int _tmain(int argc, _TCHAR* argv[])
{
//do stuff that depends on the compiler version.
VcSelector::DoStuff();
return 0;
}
It won't look quite the same as preprocessor conditionals though.

Nope. It is slightly more verbose :-)

_CRT_ASSEMBLY_VERSION is also different between RTM and SP1, but that is a
string and not usable with preprocessor conditionals.
_CPPLIB_VER is an integer, but I don't know if that changed or not.

Anyway, the above solution is a good way to impress your coworkers with
black magic C++ incantations. Just be sure to document why you are doing this.
 
The full version is conveniently named _MSC_FULL_VER
But note that versions for x86, x64 and IA32 may be different.

(sorry don't have SP1 at hand but maybe you can just take
any version number of > 14.00.50727.42 as "SP1" )

I haven't checked it, but was told in the private ng by another MVP that it
is the same for both RTM and SP1.

--

Kind regards,
Bruno van Dooren
(e-mail address removed)
Remove only "_nos_pam"
 
This won't work on x64

It doesn't have to.
The problem occurrs specifically when his DLL is used with a VC6 exe that
cannot be changed or upgraded.
I.e. the problem only exists on 32 bit platforms.
On 64 bit platforms he can use the normal way of doing things without
needing the VC version detection.

--

Kind regards,
Bruno van Dooren
(e-mail address removed)
Remove only "_nos_pam"
 
Hi Pavel!
The full version is conveniently named _MSC_FULL_VER
But note that versions for x86, x64 and IA32 may be different.

(sorry don't have SP1 at hand but maybe you can just take
any version number of > 14.00.50727.42 as "SP1" )

Exactly this is the problem: It has the *same* number for RTM and SP1!
It seems to be a "mistake".... but now it is too late ;-(

Greetiungs
Jochen
 
Pavel A. said:
This won't work on x64

The method will.

One template will use 10, the other will use sizeof (char*), which is 4 or
8. Easy to distinguish.
--PA


Bruno van Dooren said:
Since sizeof is a compile-time operator, that should be usable with
templates to select different code paths at compile time.

Thanks to Ben who gave me the idea, I have created a compile time
solution:

template <int i> class VcSelectorClass
{
public:
static char Dummy[10];
static void DoStuff(void)
{
//put code for VC2005 RTM here
cout << "RTM" << endl;
}
};

template <> class VcSelectorClass<4>
{
public:
static void DoStuff(void)
{
//put code for VC2005 SP1 here
cout << "SP1" << endl;
}
};
//typedef for making things automatic without forcing you to type too
much
garbage
typedef VcSelectorClass<sizeof(&VcSelectorClass<0>::Dummy)> VcSelector;

int _tmain(int argc, _TCHAR* argv[])
{
//do stuff that depends on the compiler version.
VcSelector::DoStuff();
return 0;
}
It won't look quite the same as preprocessor conditionals though.

Nope. It is slightly more verbose :-)

_CRT_ASSEMBLY_VERSION is also different between RTM and SP1, but that is
a
string and not usable with preprocessor conditionals.
_CPPLIB_VER is an integer, but I don't know if that changed or not.

Anyway, the above solution is a good way to impress your coworkers with
black magic C++ incantations. Just be sure to document why you are doing
this.

--
Kind regards,
Bruno.
(e-mail address removed)
Remove only "_nos_pam"
 
Back
Top