237

I found the explanation defining WIN32_LEAN_AND_MEAN "reduces the size of the Win32 header files by excluding some of the less frequently used APIs". Somewhere else I read that it speeds up the build process.

So what does WIN32_LEAN_AND_MEAN exclude exactly? Should I care about this pre-processor directive? Does it speed up the build process?

I've also seen a pre-processor directive in projects named something along the lines of extra lean. Is this another esoteric pre-processor incantation I should know about?

Joel Bodenmann
  • 2,152
  • 2
  • 17
  • 44
fishfood
  • 4,092
  • 4
  • 28
  • 35

4 Answers4

220

According the to Windows Dev Center WIN32_LEAN_AND_MEAN excludes APIs such as Cryptography, DDE, RPC, Shell, and Windows Sockets.

Chris911
  • 4,131
  • 1
  • 23
  • 33
  • 55
    I think this is the succinct answer most of us were looking for. – Dave Voyles Apr 13 '17 at 20:15
  • 11
    @DaveVoyles-MSFT and yet it doesn't even scratch the surface. For example if you want to use `winsock2.h` you better make sure `WIN32_LEAN_AND_MEAN` _is always_ defined because otherwise you will get conflicting declarations between the WinSock versions. So I like the other answer better, because it adds details missing here. Notably it shows what is the actual effect of that define. Both answers parrot documentation and yet the other one is more comprehensive, even though both fail to mention the "repercussions" of not using the define (WinSock name clashes etc). – 0xC0000022L Apr 20 '20 at 12:26
213

Directly from the Windows.h header file:

#ifndef WIN32_LEAN_AND_MEAN
    #include <cderr.h>
    #include <dde.h>
    #include <ddeml.h>
    #include <dlgs.h>
    #ifndef _MAC
        #include <lzexpand.h>
        #include <mmsystem.h>
        #include <nb30.h>
        #include <rpc.h>
    #endif
    #include <shellapi.h>
    #ifndef _MAC
        #include <winperf.h>
        #include <winsock.h>
    #endif
    #ifndef NOCRYPT
        #include <wincrypt.h>
        #include <winefs.h>
        #include <winscard.h>
    #endif

    #ifndef NOGDI
        #ifndef _MAC
            #include <winspool.h>
            #ifdef INC_OLE1
                #include <ole.h>
            #else
                #include <ole2.h>
            #endif /* !INC_OLE1 */
        #endif /* !MAC */
        #include <commdlg.h>
    #endif /* !NOGDI */
#endif /* WIN32_LEAN_AND_MEAN */

If you want to know what each of the headers actually do, typing the header names into the search in the MSDN library will usually produce a list of the functions in that header file.

Also, from Microsoft's support page:

To speed the build process, Visual C++ and the Windows Headers provide the following new defines:

VC_EXTRALEAN
WIN32_LEAN_AND_MEAN

You can use them to reduce the size of the Win32 header files.

Finally, if you choose to use either of these preprocessor defines, and something you need is missing, you can just include that specific header file yourself. Typing the name of the function you're after into MSDN will usually produce an entry which will tell you which header to include if you want to use it, at the bottom of the page.

Makonede
  • 442
  • 1
  • 6
  • 13
CuriousGeorge
  • 7,120
  • 6
  • 42
  • 74
  • Documentation for `OPENFILENAMEW` says *"commdlg.h (include Windows.h)"*, but `WIN32_LEAN_AND_MEAN` excludes `commdlg.h` from `Windows.h`. Does that mean we should include `commdlg.h` even though the documentation says "nclude `Windows.h`"? – Aykhan Hagverdili Aug 26 '20 at 04:10
  • @AyxanHaqverdili I don't think it would hurt to try it. If you get any compilation errors, you could try including `Windows.h` right before it, in case `commdlg.h` uses macros defined in `Windows.h`. – CuriousGeorge Oct 16 '20 at 05:53
8

Complementing the above answers and also "Parroting" from the Windows Dev Center documentation,

The Winsock2.h header file internally includes core elements from the Windows.h header file, so there is not usually an #include line for the Windows.h header file in Winsock applications. If an #include line is needed for the Windows.h header file, this should be preceded with the #define WIN32_LEAN_AND_MEAN macro. For historical reasons, the Windows.h header defaults to including the Winsock.h header file for Windows Sockets 1.1. The declarations in the Winsock.h header file will conflict with the declarations in the Winsock2.h header file required by Windows Sockets 2.0. The WIN32_LEAN_AND_MEAN macro prevents the Winsock.h from being included by the Windows.h header ..

0xsteve
  • 121
  • 1
  • 4
6

Here's a good answer on the motivation for it from Raymond Chen's blog: https://devblogs.microsoft.com/oldnewthing/20091130-00/?p=15863

...defining WIN32_LEAN_AND_MEAN brought you back to the 16-bit Windows philosophy of a minimal set of header files for writing a bare-bones Windows program. This appeased the programmers who liked to micro-manage their header files, and it was a big help because, at the time the symbol was introduced, precompiled header files were not in common use. As I recall, on a 50MHz 80486 with 8MB of memory, switching to WIN32_LEAN_AND_MEAN shaved three seconds off the compile time of each C file. When your project consists of 20 C files, that’s a whole minute saved right there.

Ninj0r
  • 189
  • 1
  • 4