Author Topic: missing WINVER variable  (Read 20690 times)

Raijinsetsu

  • Guest
missing WINVER variable
« on: July 14, 2006, 11:38:21 pm »
I found that neither CygWin nor C::B are setting this variable during compilation time. This causes a problem when header files un-include functions(it's assumed the version of windows you're using does not support them). I found this problem when using the socket functions "getaddrinfo()" and "freeaddrinfo()", which are now the standard for name resolution when using sockets("gethostbyname()" and "gethostbyaddr()" have been deprecated in both windows and linux). After searching every header file in my CygWin install, I found this:
Line 297 of /usr/include/w32api/ws2tcpip.h
#if _WIN32_WINNT >= 0x0501
This if clause contained the definitions for the functions I was trying to use. _WIN32_WINNT is set to WINVER in a previous header file.

Maybe C::B should automatically define this variable during installation, because I certainly had a hell of a time finding out why the fully documented functions were "not defined" in C::B.
« Last Edit: July 14, 2006, 11:40:58 pm by Raijinsetsu »

Offline kidmosey

  • Multiple posting newcomer
  • *
  • Posts: 95
    • MUSITU International
Re: missing WINVER variable
« Reply #1 on: July 15, 2006, 01:13:10 am »
http://msdn.microsoft.com/library/en-us/winprog/winprog/using_the_windows_headers.asp

Quote from: MSDN Library
You can define these symbols [WINVER, WIN32_LEAN_AND_MEAN] by using the #define statement in each source file, or by specifying the /D compiler option supported by Visual C++.

You need to define this variable yourself, either in project settings or before each inclusion of the windows headers.  It works the same as WIN32_LEAN_AND_MEAN; the compiler and IDE have no way of knowing what you want to use for these variables.  Alternatively, you could create your own template to automatically define these.
3 years until google knows more than god.

Raijinsetsu

  • Guest
Re: missing WINVER variable
« Reply #2 on: July 15, 2006, 06:03:56 am »
I know that you CURRENTLY need to define these yourself, BUT, if, on installation, C::B set WINVER to your windows version, then programmers would not have to worry about why certain functions are showing up as "undefined". When using Visual Studio, these variables are in the compiler, so you don't have to define them. It would be much easier if C::B defined this automatically. Maybe in future versions of C::B?

Offline Ceniza

  • Developer
  • Lives here!
  • *****
  • Posts: 1441
    • CenizaSOFT
Re: missing WINVER variable
« Reply #3 on: July 15, 2006, 06:46:26 am »
Raijinsetsu: I think the approach you're suggesting is really invasive for an IDE. Code::Blocks shouldn't define anything at your back trying to guess what's better for some people. Setting those defines is really up to the programmer and it's his/her choice to decide if the executable will only run with that Instruction Set, CPU and/or OS version because of it or if it'll be more compatible.

Using defines like those could make your executable run on 2k+ but not on 9x/ME, on a P4 but not on a PIII, .... It's really a programmer's choice.

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: missing WINVER variable
« Reply #4 on: July 15, 2006, 10:44:23 am »
Ceniza explained it well. An IDE must not do such things behind the scenes.

In particular, I wonder if you fully understand what these macros are about. Or, you seem to assume that all the programs you write will only ever run on the same machine that you use for programming them, and you never plan to write any kind of thing for anybody else?
This:
Quote
When using Visual Studio, these variables are in the compiler, so you don't have to define them.
is certainly not true. It cannot be true. If Visual Studio was setting WINVER=0x501 as a general rule, then you could not write programs that work on anything older than Windows XP. This is certainly not the case.
I don't know how exactly it is handled in Visual Studio (as I don't use this particular product), but very likely there is a choice box in the project settings that lets you define this variable and which defaults to either nothing or a "reasonably low value".

If you want to have this compiler switch added to all your projects, you can modify your project template, but there is no way we could add a feature that willingly and consciously breaks compatibility for the majority of Windows users.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline kidmosey

  • Multiple posting newcomer
  • *
  • Posts: 95
    • MUSITU International
Re: missing WINVER variable
« Reply #5 on: July 15, 2006, 01:25:00 pm »
I don't know how exactly it is handled in Visual Studio (as I don't use this particular product), but very likely there is a choice box in the project settings that lets you define this variable and which defaults to either nothing or a "reasonably low value".

I deleted Visual Studio once I installed C::B *grin*, but if I remember correctly, I think VS does ask you which version of windows you will be compiling for, or at the very least has a dropdown for it hidden somewhere in it's maze of configuration settings.  But since C::B is multi-platform, it doesn't seem viable to include "Windows Version" as an option.
3 years until google knows more than god.

Raijinsetsu

  • Guest
Re: missing WINVER variable
« Reply #6 on: July 15, 2006, 03:08:43 pm »
Basically WINVER means you have the set of Windows DLLs corresponding to version X of windows. In all my Visual Studio crawling, I've never seen a compiler flag or setting(on the command line) that sets this macro. Maybe it's hidden from the user? You know MS likes to be tricky, or just plain mean.
However, having read the above posts, I can agree that for the sake of portability, C::B shouldn't automatically set it. However, it should be noted that anyone trying to make cross-platform sockets with CygWin(maybe even with MinGW, I think they have the same includes) and C::B, will have to use obselete and deprecated functions.
gethostbyname, and gethostbyaddr have been deprecated on both linux and windows. Their replacement, getaddrinfo, and it's compliment, freeaddrinfo, will only be available(in a CygWin compile) if WINVER is set >= 0x0501. This is a portability issue because these functions are defined in linux without this.

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9723
Re: missing WINVER variable
« Reply #7 on: July 15, 2006, 03:22:29 pm »
I believe the WINVER is defined inside some of the plenty header files for the MSVC SDK. Thus it depends on the version of the (platform) SDK you are using. The platform SDK I'm using currently defines WINVER just in Windows.h which you ususally include in your MS projects. Within the platform SDK it is defined to 0x0501, whereas in the SDK of MSVC version 6 (the "old" Visual Studio) it is defined e.g. to WINVER 0x0400.
Thus it depends on what SDK version (version of libs) you are using.
With regards, Morten.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: https://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: https://wiki.codeblocks.org/index.php?title=FAQ

Raijinsetsu

  • Guest
Re: missing WINVER variable
« Reply #8 on: July 15, 2006, 03:44:39 pm »
I believe the WINVER is defined inside some of the plenty header files for the MSVC SDK. Thus it depends on the version of the (platform) SDK you are using. The platform SDK I'm using currently defines WINVER just in Windows.h which you ususally include in your MS projects. Within the platform SDK it is defined to 0x0501, whereas in the SDK of MSVC version 6 (the "old" Visual Studio) it is defined e.g. to WINVER 0x0400.
Thus it depends on what SDK version (version of libs) you are using.
With regards, Morten.

So this means that the missing WINVER macro is actually a problem with CygWin/MinGW... Thanks Mort.

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9723
Re: missing WINVER variable
« Reply #9 on: July 15, 2006, 05:03:18 pm »
So this means that the missing WINVER macro is actually a problem with CygWin/MinGW...
Sorry, but no: I don't thinks so. WINVER is defined within windef.h in my MinGW GCC compiler installation. winver.h is included from windows.h which (again) I believe you need to include in any Win32 application you are trying to implement. So please try to change your project in a way it includes windows.h early in the beginning and all your issues should be gone. Please remember: This only applies if you are programming Win32 API. For a MinGW console app or wxWidgets (for example) you don't need to do this (or it is "done by the wxWidgets headers", if needed).
With regards, Morten.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: https://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: https://wiki.codeblocks.org/index.php?title=FAQ

Raijinsetsu

  • Guest
Re: missing WINVER variable
« Reply #10 on: July 15, 2006, 07:08:28 pm »
You're right mort, it's there in the windef.h, but it's set to 0x0400, which is windows 95... Who uses win95 anyways?
If I define my own WINVER on the command line, it works.

Thanks

Offline kkez

  • Almost regular
  • **
  • Posts: 153
    • WinapiZone
Re: missing WINVER variable
« Reply #11 on: July 15, 2006, 10:15:59 pm »
This:
Quote
When using Visual Studio, these variables are in the compiler, so you don't have to define them.
is certainly not true. It cannot be true. If Visual Studio was setting WINVER=0x501 as a general rule, then you could not write programs that work on anything older than Windows XP.
Actually those flags (_WINVER, _WIN32_WINNT, _WIN32_IE) only enable some structure, structure members or flags that are only available under a certain version of windows. If you define them but do not use any of these new elements then you're ok with every windows version :)
« Last Edit: July 15, 2006, 10:17:51 pm by kkez »

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: missing WINVER variable
« Reply #12 on: July 16, 2006, 12:34:34 am »
Quote
So this means that the missing WINVER macro is actually a problem with CygWin/MinGW
Problem is not the correct word. MinGW (or gcc in general) is a compiler that is first and for all designed for compatibility and standard compliance. Only after this, it is designed for things like optimisations or system-dependent features.
It has to work, and it has to be right. Everything else is second line.

The default value of WINVER chosen by MinGW is a safe value that guarantees it works everywhere. If you accidentially use something that would prevent your program from running on older, then you will know. It will not compile without errors and mysteriously crash later (or fail due to a missing DLL), but it will tell you before things get nasty on the target PC.
That way, the developer can decide what to do in time (either change minimum requirements or use different functions).
This is a very good strategy, it saves you a lot of support work and headaches later.

If you're positive about not wanting to support anything older than Windows XP, you can always -DWINVER=0x501 or anything in your project settings, it is neither obscure nor hidden, nor anything of that kind, and it works just fine. It will just not work on an older OS, but you know it won't.

Quote
Who uses win95 anyways?
Where I live, almost nobody uses Windows 95/98/ME any more (although a few people exist who still do). It may be the same where you live.
However, you have to take into account that the majority of people that live on this planet are not exactly as lucky as you and me.
In fact, for far more than two thirds of this planet's population, a Pentium III with Windows 98 is something so surreal that they would not even think about ever owning one. Therefore, you should not assume that nobody uses Windows 9x any more.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: missing WINVER variable
« Reply #13 on: July 16, 2006, 01:04:12 am »
Quote
If you define them but do not use any of these new elements then you're ok with every windows version
Ah sorry, did not see this before.
Although you are technically right with this, I still cannot agree.
WINVER can be thought of as a parachute. It is a measure that is somewhat similar to type checking in the compiler.

Technically, type checking is absolutely useless and it is plain annoying, too. It is a lot of extra work which you actually don't need. You can do everything with void* all over the place, and you can mix char, int, and long all the time. Yeah, you know that if you copy a long value to a char variable, then it would better be smaller than 255. So what, you remember that. Why is the compiler so pedantic about this!
Well, the truth is that we are human beings, and as such we make mistakes. Type checking makes sure we detect these mistakes early.

The same goes for WINVER. If we never use a non-supported function, then all is fine. However, sooner or later, you will forget that you may not use one particular function, and you will use it.
If there is no such thing as WINVER, then the compiler will build your program just fine (supposed your headers and libraries are up to date). But then, after you have spent a lot of time and money, thousands of support calls keep coming in and people ask their money back because your program does not work for them (other than expected).
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."