RandomNumber Generators
consoleprograms and DLLs with Microsoft’s Visual C compilers, without the (bloat, bugs and overhead of the) MSVCRT runtime libraries, using only functions of the Win32 API, for use on Windows™ XP and newer versions of Windows NT as well as Windows PE.
The minimalist Win32 runtime library provides the compiler helper routines, internal functions and intrinsics called from objects created with Microsoft’s Visual C compiler, the startup routines called from Windows’ module loader, plus various basic as well as extraneous runtime functions.
Note: the minimalist Win32 runtime
library is not (intended to be) a C
standard runtime library,
it offers (almost) no
ANSI C,
ISO C
or
POSIX
functions like
longjmp()
,
qsort()
,
scanf()
,
setjmp()
or
strerror()
,
no objects like FILE
and functions like
ferror()
which operate on them, and no global variables like
errno
or
stderr
,
but functions which replace
cprintf()
,
fputchar()
,
printf()
,
putch()
,
puts()
,
putw()
etc.
The MSKB article 99456 lists some equivalent functions of the Win32 API.
Download the makefile
NOMSVCRT.MAK
into an arbitrary, preferable empty directory.
Note: the makefile
contains the sources as
inline files
.
Run the following command line to build the object library
NOMSVCRT.LIB
for the I386 alias
x86 processor architecture:
NMAKE.EXE /R /F NOMSVCRT.MAKNote: if necessary, see the MSDN article Use the Microsoft C++ toolset from the command line for an introduction.
Microsoft (R) Program Maintenance Utility Version 10.00.40219.01 Copyright (C) Microsoft Corporation. All rights reserved. ML.EXE /Brepro /Cp /Cx /c /coff /FoALLOCA.OBJ /nologo /safeseh /TanmFC87.tmp /W3 /X Assembling: nmFC87.tmp … ML.EXE /Brepro /Cp /Cx /c /coff /DJccLess /FoUDIV128.OBJ /nologo /safeseh /TanmFC9B.tmp /W3 /X Assembling: nmFC9B.tmp … CL.EXE /Brepro /c /DSPECIAL /FoFLTUSED.OBJ /fp:precise /GA /Gd /GF /GS /Gy /nologo /O2 /QIfist /TcnmFCA1.tmp /W4 /wd4201 /wd4204 /wd4214 /Zl cl : Command line warning D9035 : option 'QIfist' has been deprecated and will be removed in a future release nmFCA1.tmp nmfca1.tmp(2027) : warning C4057: 'function' : 'unsigned int *' differs in indirection to slightly different base types from 'int *' nmfca1.tmp(2576) : warning C4244: '=' : conversion from '__int64' to 'double', possible loss of data nmfca1.tmp(2612) : warning C4244: '=' : conversion from 'unsigned __int64' to 'double', possible loss of data nmfca1.tmp(2972) : warning C4244: '=' : conversion from '__int64' to 'double', possible loss of data nmfca1.tmp(3008) : warning C4244: '=' : conversion from 'unsigned __int64' to 'double', possible loss of data … ML.EXE /Brepro /Cp /Cx /c /coff /DJones /FoCNTR64.OBJ /nologo /safeseh /TanmFCD5.tmp /W3 /X Assembling: nmFCD5.tmp … ML.EXE /Brepro /Cp /Cx /c /coff /FoMSQR32.OBJ /nologo /safeseh /TanmFCD8.tmp /W3 /X Assembling: nmFCD8.tmp … ML.EXE /Brepro /Cp /Cx /c /coff /FoWMEMSWAP.OBJ /nologo /safeseh /TanmFD09.tmp /W3 /X Assembling: nmFD09.tmp CL.EXE /Brepro /c /FoDLLMAIN.OBJ /GA /GF /GS /Gy /nologo /O1 /Os /TcnmFD0A.tmp /W4 /wd4100 /we4013 /Zl nmFD0A.tmp CL.EXE /Brepro /c /FoWINMAIN.OBJ /GA /GF /GS /Gy /nologo /O1 /Os /TcnmFD0B.tmp /W4 /wd4090 /wd4100 /wd4189 /we4013 /Zl nmFD0B.tmp CL.EXE /Brepro /c /FoWWINMAIN.OBJ /GA /GF /GS /Gy /nologo /O1 /Os /TcnmFD0C.tmp /W4 /wd4090 /wd4100 /wd4189 /we4013 /Zl nmFD0C.tmp CL.EXE /Brepro /c /DKEYPRESS /FoWMAIN.OBJ /GA /GF /GS /Gy /nologo /O1 /Oi /Os /TcnmFD0D.tmp /W4 /wd4090 /wd4100 /wd4201 /we4013 /Zl nmFD0D.tmp nmFD0D.tmp(360) : warning C4996: 'wcscpy': This function or variable may be unsafe. Consider using wcscpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. CL.EXE /Brepro /c /DKEYPRESS /FoMAIN.OBJ /GA /GF /GS /Gy /nologo /O1 /Oi /Os /TcnmFD0E.tmp /W4 /wd4090 /wd4100 /wd4201 /we4013 /Zl nmFD0E.tmp nmFD0E.tmp(333) : warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. CL.EXE /Brepro /c /FoNOMSVCRT.OBJ /GA /GF /GS /Gy /nologo /O1 /Os /TcnmFD0F.tmp /W4 /wd4047 /wd4201 /we4013 /Zl nmFD0F.tmp LINK.EXE /LIB /BREPRO /MACHINE:I386 /NODEFAULTLIB /NOLOGO /OUT:NOMSVCRT.LIB ALLOCA.OBJ ALLOCA4.OBJ ALLOCA8.OBJ ALLOCA16.OBJ ALLABS.OBJ ALLCMP.OBJ ALLDIV.OBJ ALLDVRM.OBJ ALLMUL.OBJ ALLNEG.OBJ ALLREM.OBJ ALLROL.OBJ ALLROR.OBJ ALLSGN.OBJ ALLSHL.OBJ ALLSHR.OBJ AULLCMP.OBJ AULLDIV.OBJ AULLDVRM.OBJ AULLREM.OBJ AULLSHR.OBJ MUL128.OBJ MULH.OBJ UDIV128.OBJ UMUL128.OBJ UMULH.OBJ CIACOS.OBJ CIASIN.OBJ CIATAN.OBJ CIATAN2.OBJ CICOS.OBJ CICOSH.OBJ CIEXP.OBJ CIFMOD.OBJ CILOG.OBJ CILOG10.OBJ CIPOW.OBJ CISIN.OBJ CISINH.OBJ CISQRT.OBJ CITAN.OBJ CITANH.OBJ FABS.OBJ FCEIL.OBJ FCOPYSIGN.OBJ FDIM.OBJ FFLOOR.OBJ FFREXP.OBJ FHYPOT.OBJ FLDEXP.OBJ FLOGB.OBJ FMAX.OBJ FMIN.OBJ FNEXT.OBJ FPOWN.OBJ FRAND.OBJ FREMAINDER.OBJ FREMQUO.OBJ FRINT.OBJ FROUND.OBJ FSIGNBIT.OBJ FTRUNC.OBJ FACOSH.OBJ FACOT.OBJ FACOT2.OBJ FACOTH.OBJ FASINH.OBJ FATANH.OBJ FCOT.OBJ FCOTH.OBJ FEXP2.OBJ FEXP10.OBJ FEXPM1.OBJ FLOG.OBJ FLOG1P.OBJ FLOG2.OBJ FLOG10.OBJ FLTUSED.OBJ FTOL.OBJ FTOL2.OBJ FTOL2SSE.OBJ MODF.OBJ ILOGB.OBJ SWAB.OBJ HTONLL.OBJ HTONL.OBJ HTONS.OBJ LABS.OBJ LMAX.OBJ LMIN.OBJ LSGN.OBJ LZCNT32.OBJ LZCNT64.OBJ TZCNT32.OBJ TZCNT64.OBJ CNTR32.OBJ CNTR64.OBJ LFSR32.OBJ LFSR64.OBJ LFSR128.OBJ MSQR32.OBJ MSQR64.OBJ MWCG32.OBJ MWCG64.OBJ REV8.OBJ REV16.OBJ REV32.OBJ REV64.OBJ LMEMCHR.OBJ LMEMCMP.OBJ LMEMCPY.OBJ LMEMMOVE.OBJ LMEMSET.OBJ LMEMSWAP.OBJ MEMCHR.OBJ MEMCMP.OBJ MEMCPY.OBJ MEMMOVE.OBJ MEMSET.OBJ MEMSWAP.OBJ STRCAT.OBJ STRCHR.OBJ STRCMP.OBJ STRCPY.OBJ STRCSPN.OBJ STRLEN.OBJ STRNCAT.OBJ STRNCMP.OBJ STRNCPY.OBJ STRNSET.OBJ STRPBRK.OBJ STRRCHR.OBJ STRREV.OBJ STRSET.OBJ STRSPN.OBJ STRSTR.OBJ STRTOKR.OBJ WCSCAT.OBJ WCSCHR.OBJ WCSCMP.OBJ WCSCPY.OBJ WCSLEN.OBJ WCSNCAT.OBJ WCSNCMP.OBJ WCSNCPY.OBJ WCSNSET.OBJ WCSRCHR.OBJ WCSREV.OBJ WCSSET.OBJ WCSSTR.OBJ WMEMCHR.OBJ WMEMCMP.OBJ WMEMCPY.OBJ WMEMMOVE.OBJ WMEMSET.OBJ WMEMSWAP.OBJ DLLMAIN.OBJ WINMAIN.OBJ WWINMAIN.OBJ WMAIN.OBJ MAIN.OBJ NOMSVCRT.OBJ FLOG.OBJ : warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library FEXP10.OBJ : warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library FEXP2.OBJ : warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this libraryNote: a
makefilewhich builds the object library
NOMSVCRT.LIB
for the AMD64 alias
x64 processor architecture is available upon request.
Download the header
file
NOMSVCRT.H
and the
ANSI C
source file
NOMSVCRT.C
into the directory used in steps 1. and 2.
Run the following command lines to build the sample
GUI alias
Windows application
NOMSVCRT.EXE
,
the sample DLL
NOMSVCRT.DLL
and the sample
CUI or
CLI alias
console
program
NOMSVCRT.COM
:
SET CL=/Brepro /GA /GF /GS /Gy /O1 /Os /Oy /W4 /Zl SET LINK=/BREPRO /DYNAMICBASE /LARGEADDRESSAWARE /NOCOFFGRPINFO /NXCOMPAT /OPT:REF /OSVERSION:5.1 /RELEASE CL.EXE NOMSVCRT.C CL.EXE /DUNICODE NOMSVCRT.C CL.EXE /LD /MD NOMSVCRT.C CL.EXE /DCONSOLE /FeNOMSVCRT.COM NOMSVCRT.C CL.EXE /DCONSOLE /DUNICODE /FeNOMSVCRT.COM NOMSVCRT.CFor details and reference see the MSDN articles Compiler Options and Linker Options.
Note: if necessary, see the MSDN article Use the Microsoft C++ toolset from the command line for an introduction.
Note: the command lines can be copied and pasted as block into a Command Processor window.
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. NOMSVCRT.C NOMSVCRT.C(288) : warning C4100: 'nCmdShow' : unreferenced formal parameter NOMSVCRT.C(286) : warning C4100: 'hPrevInstance' : unreferenced formal parameter NOMSVCRT.C(285) : warning C4100: 'hInstance' : unreferenced formal parameter Microsoft (R) Incremental Linker Version 10.00.40219.386 Copyright (C) Microsoft Corporation. All rights reserved. /DYNAMICBASE /LARGEADDRESSAWARE /NOCOFFGRPINFO /NXCOMPAT /OPT:REF /OSVERSION:5.1 /RELEASE /out:NOMSVCRT.exe NOMSVCRT.obj Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. NOMSVCRT.C Microsoft (R) Incremental Linker Version 10.00.40219.386 Copyright (C) Microsoft Corporation. All rights reserved. /DYNAMICBASE /LARGEADDRESSAWARE /NOCOFFGRPINFO /NXCOMPAT /OPT:REF /OSVERSION:5.1 /RELEASE /out:NOMSVCRT.exe NOMSVCRT.obj Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. NOMSVCRT.C Microsoft (R) Incremental Linker Version 10.00.40219.386 Copyright (C) Microsoft Corporation. All rights reserved. /DYNAMICBASE /LARGEADDRESSAWARE /NOCOFFGRPINFO /NXCOMPAT /OPT:REF /OSVERSION:5.1 /RELEASE /out:NOMSVCRT.dll /dll /implib:NOMSVCRT.lib NOMSVCRT.obj Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. NOMSVCRT.C Microsoft (R) Incremental Linker Version 10.00.40219.386 Copyright (C) Microsoft Corporation. All rights reserved. /DYNAMICBASE /LARGEADDRESSAWARE /NOCOFFGRPINFO /NXCOMPAT /OPT:REF /OSVERSION:5.1 /RELEASE /out:NOMSVCRT.COM NOMSVCRT.obj Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. NOMSVCRT.C Microsoft (R) Incremental Linker Version 10.00.40219.386 Copyright (C) Microsoft Corporation. All rights reserved. /DYNAMICBASE /LARGEADDRESSAWARE /NOCOFFGRPINFO /NXCOMPAT /OPT:REF /OSVERSION:5.1 /RELEASE /out:NOMSVCRT.COM NOMSVCRT.objEach resulting
portable executablefile is just 4 kB to 7 kB small.
Note: the downloadable sample
portable executable
files are a bit larger, they result from the optional step 8.
Start the sample application NOMSVCRT.EXE
built in
step 4., either per double-click or on the command line,
optionally with arbitrary arguments: it displays a message box like
that shown on the right.
Run one of the following command lines to load the sample
DLL
NOMSVCRT.DLL
built in step 4.:
MSIEXEC.EXE /Y "%CD%\NOMSVCRT.DLL" REGSVR32.EXE "%CD%\NOMSVCRT.DLL" RUNDLL32.EXE "%CD%\NOMSVCRT.DLL",#0 RUNDLL32.EXE "%CD%\NOMSVCRT.DLL",foobarNote: on 64-bit editions of Windows, the execution environments of
NOMSVCRT.DLL
and
MSIExec.exe
must
match!
Windows’ module loader executes the DLL’s startup routine, which displays two message boxes like those shown below:
Note: the error message boxes displayed from
RegSvr32.exe
and
RunDLL32.exe
are expected:
NOMSVCRT.DLL
does neither implement any of the functions
DllInstall()
,
DllRegisterServer()
and
DllUnregisterServer()
called from the
Regsvr32 tool,
nor the
Rundll32 Interface.
Run the following command line to execute the console
program
NOMSVCRT.COM
built in step 4.:
NOMSVCRT.COM foo\"bar\\bazIt
printsoutput like the following text:
argc: 2 argv[0]: 0x0046FB3C NOMSVCRT.COM argv[1]: 0x0046FB58 foo"bar\\baz envp[0]: 0x008B0B18 ALLUSERSPROFILE=C:\ProgramData envp[1]: 0x008B0B56 APPDATA=C:\Users\Stefan\AppData\Roaming envp[2]: 0x008B0BA6 CommonProgramFiles=C:\Program Files (x86)\Common Files envp[3]: 0x008B0C14 CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files envp[4]: 0x008B0C8C CommonProgramW6432=C:\Program Files\Common Files envp[5]: 0x008B0CEE COMPUTERNAME=AMNESIAC envp[6]: 0x008B0D1A ComSpec=C:\Windows\system32\cmd.exe envp[7]: 0x008B0D62 COPYCMD=/V /Z envp[8]: 0x008B0D7E DevMgr_Show_Details=* envp[9]: 0x008B0DAA DevMgr_Show_NonPresent_Devices=* envp[10]: 0x008B0DEC DIRCMD=/A /P /X envp[11]: 0x008B0E0C FP_NO_HOST_CHECK=NO envp[12]: 0x008B0E34 HOMEDRIVE=C: envp[13]: 0x008B0E4E HOMEPATH=\Users\Stefan envp[14]: 0x008B0E7C LOCALAPPDATA=C:\Users\Stefan\AppData\Local envp[15]: 0x008B0ED2 LOGONSERVER=\\AMNESIAC envp[16]: 0x008B0F00 NUMBER_OF_PROCESSORS=2 envp[17]: 0x008B0F2E OS=Windows_NT envp[18]: 0x008B0F4A Path=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\Commands;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Program Files\Microsoft SDKs\Windows\v7.0\bin envp[19]: 0x008B10A4 PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC envp[20]: 0x008B1120 PROCESSOR_ARCHITECTURE=x86 envp[21]: 0x008B1156 PROCESSOR_ARCHITEW6432=AMD64 envp[22]: 0x008B1190 PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 23 Stepping 10, GenuineIntel envp[23]: 0x008B1222 PROCESSOR_LEVEL=6 envp[24]: 0x008B1246 PROCESSOR_REVISION=170a envp[25]: 0x008B1276 ProgramData=C:\ProgramData envp[26]: 0x008B12AC ProgramFiles=C:\Program Files (x86) envp[27]: 0x008B12F4 ProgramFiles(x86)=C:\Program Files (x86) envp[28]: 0x008B1346 ProgramW6432=C:\Program Files envp[29]: 0x008B1382 PROMPT=$P$G envp[30]: 0x008B139A PSModulePath=C:\Windows\system32\WindowsPowerShell\v1.0\Modules\ envp[31]: 0x008B141C PUBLIC=C:\Users\Public envp[32]: 0x008B144A SystemDrive=C: envp[33]: 0x008B1468 SystemRoot=C:\Windows envp[34]: 0x008B1494 TEMP=C:\Users\Stefan\AppData\Local\Temp envp[35]: 0x008B14E4 TMP=C:\Users\Stefan\AppData\Local\Temp envp[36]: 0x008B1532 USERDOMAIN=AMNESIAC envp[37]: 0x008B155A USERDOMAIN_ROAMINGPROFILE=AMNESIAC envp[38]: 0x008B15A0 USERNAME=Stefan envp[39]: 0x008B15C0 USERPROFILE=C:\Users\Stefan envp[40]: 0x008B15F8 windir=C:\WindowsNote: when started in its own
consolewindow, for example per double-click,
NOMSVCRT.COM
waits for a keypress before it exits and its consolewindow closes; it beeps once and flashes the title bar of its
consolewindow to indicate this wait state.
Optionally download the icon
file
NOMSVCRT.ICO
into the directory used in steps 1. to 3., then run the following
command line to build the three sample executable files with
(almost) all bells and whistles, i.e. including a
resource
containing the icon, an
Application Manifest
and
version information
,
plus a custom DOS stub, and
digitally sign
them with your own
X.509
certificate:
NMAKE.EXE /R /F NOMSVCRT.MAK samples signNote: if necessary, see the MSDN article Use the Microsoft C++ toolset from the command line for an introduction.
Microsoft (R) Program Maintenance Utility Version 10.00.40219.01 Copyright (C) Microsoft Corporation. All rights reserved. CERTUTIL.EXE /DecodeHex /F /V nm34A.tmp NOMSVCRT.DOS Input Length = 657 Output Length = 144 CertUtil: -decodehex command completed successfully. RC.EXE /DUNICODE /FoNOMSVCRT.RES /L 0 /N /R /V nm34B.tmp Microsoft (R) Windows (R) Resource Compiler Version 6.1.7600.16385 Copyright (C) Microsoft Corporation. All rights reserved. Using codepage 1252 as default Creating NOMSVCRT.RES C:\Program Files\Microsoft Visual Studio 10.0\Include\string.h(54) : warning RC4011: identifier truncated to '_CRT_SECURE_CPP_OVERLOAD_STANDA' C:\Program Files\Microsoft Visual Studio 10.0\Include\string.h(76) : warning RC4011: identifier truncated to '_CRT_SECURE_CPP_OVERLOAD_SECURE' nm34B.tmp. Writing ICON:1, lang:0x0, size 9640 Writing ICON:2, lang:0x0, size 4264 Writing ICON:3, lang:0x0, size 1128 Writing GROUP_ICON:1, lang:0x0, size 48. Writing 24:1, lang:0x0, size 1305. Writing VERSION:1, lang:0x0, size 1188 CVTRES.EXE /BREPRO /MACHINE:I386 /NOLOGO /OUT:NOMSVCRT.CVT /READONLY NOMSVCRT.RES CL.EXE /Brepro /c /DUNICODE /FoNOMSVCRT.TMP /GA /GF /GS /Gy /I. /J /nologo /O1 /Os /TcNOMSVCRT.C /W4 /we4013 /Zl NOMSVCRT.C LINK.EXE /LINK /BREPRO /DEFAULTLIB:NOMSVCRT.LIB /DYNAMICBASE /ENTRY:wWinMainCRTStartup /LARGEADDRESSAWARE /MACHINE:I386 /NOCOFFGRPINFO /NOLOGO /NXCOMPAT/OPT:REF /OSVERSION:5.1 /OUT:NOMSVCRT.EXE /RELEASE /SAFESEH /STUB:NOMSVCRT.DOS /SUBSYSTEM:WINDOWS /SWAPRUN:CD,NET /TEST /VERSION:0.815 NOMSVCRT.TMP NOMSVCRT.CVT LINK : file alignment: 512, section alignment: 4096 LINK : section '.sdata' (C0000040) merged into '.data' (C0000040) LINK : section '.xdata' (40000040) merged into '.rdata' (40000040) Erase NOMSVCRT.TMP CL.EXE /Brepro /c /FoNOMSVCRT.TMP /GA /GF /GS /Gy /I. /J /MD /nologo /O1 /Os /TcNOMSVCRT.C /W4 /we4013 /Zl NOMSVCRT.C LINK.EXE /LINK /BREPRO /DEFAULTLIB:NOMSVCRT.LIB /DLL /DYNAMICBASE /ENTRY:_DllMainCRTStartup@12 /LARGEADDRESSAWARE /MACHINE:I386 /NOCOFFGRPINFO /NOLOGO /NXCOMPAT /OPT:REF /OSVERSION:5.1 /OUT:NOMSVCRT.DLL /RELEASE /SAFESEH /STUB:NOMSVCRT.DOS /SUBSYSTEM:WINDOWS /SWAPRUN:CD,NET /TEST /VERSION:0.815 NOMSVCRT.TMP NOMSVCRT.CVT LINK : file alignment: 512, section alignment: 4096 LINK : section '.sdata' (C0000040) merged into '.data' (C0000040) LINK : section '.xdata' (40000040) merged into '.rdata' (40000040) Erase NOMSVCRT.TMP CL.EXE /Brepro /c /DCONSOLE /DUNICODE /FoNOMSVCRT.TMP /GA /GF /GS /Gy /I. /J /nologo /O1 /Os /TcNOMSVCRT.C /W4 /we4013 /Zl NOMSVCRT.C LINK.EXE /LINK /BREPRO /DEFAULTLIB:NOMSVCRT.LIB /DYNAMICBASE /ENTRY:wmainCRTStartup /LARGEADDRESSAWARE /MACHINE:I386 /NOCOFFGRPINFO /NOLOGO /NXCOMPAT /OPT:REF /OSVERSION:5.1 /OUT:NOMSVCRT.COM /RELEASE /SAFESEH /STUB:NOMSVCRT.DOS /SUBSYSTEM:CONSOLE /SWAPRUN:CD,NET /TEST /VERSION:0.815 NOMSVCRT.TMP NOMSVCRT.CVT LINK : file alignment: 512, section alignment: 4096 LINK : section '.sdata' (C0000040) merged into '.data' (C0000040) LINK : section '.xdata' (40000040) merged into '.rdata' (40000040) Erase NOMSVCRT.TMP ".\NOMSVCRT.EXE" foobar "foobaz" "foo\\bar" foo\\" "baz foo\\\"bar \\"foo baz" RUNDLL32.EXE ".\NOMSVCRT.DLL",foobar ".\NOMSVCRT.COM" foobar "foobaz" "foo\\bar" foo\\" "baz foo\\\"bar \\"foo baz" SIGNTOOL.EXE Sign /A /D "NOMSVCRT Sample Application, Console Program or DLL" /DU "https://skanthak.hier-im-netz.de/nomsvcrt.html" /T "http://timestamp.digicert.com/" /V NOMSVCRT.EXE NOMSVCRT.DLL NOMSVCRT.COM The following certificate was selected: Issued to: Stefan Kanthak Issued by: eSKamation Certification Authority Expires: Thu Feb 22 22:27:43 2052 SHA1 hash: 1459BCFF425225185367AE33591DA1A84ECBA07C Attempting to sign: NOMSVCRT.EXE NOMSVCRT.DLL NOMSVCRT.COM Successfully signed and timestamped: NOMSVCRT.EXE NOMSVCRT.DLL NOMSVCRT.COM Number of files successfully Signed: 3 Number of warnings: 0 Number of errors: 0
Finally move the header
file NOMSVCRT.H
downloaded in step 3. into one of the
include
directories used by the Visual C compiler, and the
object library NOMSVCRT.LIB
built in step 2. into
one of the
lib
directories for the
I386 alias x86
appropriate processor architecture.
// Copyright © 2004-2024, Stefan Kanthak <stefan.kanthak@nexgo.de>
// Minimalist Win32 Runtime Library for Microsoft C Compiler 20xy
#define NOMINMAX
#define STRICT
#define WIN32_LEAN_AND_MEAN
#define WINVER 0x0500
#define _WIN32_WINNT 0x0500
#include <windows.h>
…
#define IEEE_754 // for floating-point routines
#define INTRINSIC // for intrinsics
#include <nomsvcrt.h>
…
#ifdef _DLL
// see <https://msdn.microsoft.com/en-us/library/ms682583.aspx>
// and <https://msdn.microsoft.com/en-us/library/ms682596.aspx>
BOOL WINAPI DllMain(HANDLE hModule,
DWORD dwReason,
LPVOID lpReserved)
{
…
return dwReason == DLL_PROCESS_ATTACH;
}
#else // _DLL
#ifdef CONSOLE
#ifdef UNICODE
// see <https://msdn.microsoft.com/en-us/library/6wd819wh.aspx>
// and <https://msdn.microsoft.com/en-us/library/bky3b5dh.aspx>
int wmain(int argc, wchar_t *argv[], wchar_t *envp[])
{
return PrintString(STDOUT, L"Hello world!\n");
}
#else // ANSI
// see <https://msdn.microsoft.com/en-us/library/3ze4ytsc.aspx>
// and <https://msdn.microsoft.com/en-us/library/6wd819wh.aspx>
int main(int argc, char *argv[], char *envp[])
{
return PrintString(STDOUT, "Hello world!\n");
}
#endif // UNICODE
#else // WINDOWS
#ifdef UNICODE
// see <https://msdn.microsoft.com/en-us/library/ms633559.aspx>
// and <https://msdn.microsoft.com/en-us/library/ff381406.aspx>
INT WINAPI wWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
INT nCmdShow)
{
// see <https://msdn.microsoft.com/en-us/library/ms645507.aspx>
return MessageBoxEx(HWND_DESKTOP, L"Hello world!\n", L"NOMSVCRT", MB_OK, MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL));
}
#else // ANSI
// see <https://msdn.microsoft.com/en-us/library/ms633559.aspx>
// and <https://msdn.microsoft.com/en-us/library/ff381406.aspx>
INT WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
INT nCmdShow)
{
// see <https://msdn.microsoft.com/en-us/library/ms645507.aspx>
return MessageBoxEx(HWND_DESKTOP, "Hello world!\n", "NOMSVCRT", MB_OK, MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL));
}
#endif // UNICODE
#endif // CONSOLE
#endif // _DLL
CL.EXE /GA /GF /GS /Gy /Oi /Zl … ‹source›.cFor details and reference see the MSDN articles Compiler Options and Linker Options.
Note: if necessary, see the MSDN article Use the Microsoft C++ toolset from the command line for an introduction.
WINDOWS.H
must be included before
NOMSVCRT.H
.
Note: the functions max()
and
min()
are defined only when the corresponding
preprocessor macros
max
and
min
are not defined; to disable their definition, define the
preprocessor macro NOMINMAX
before you include
WINDOWS.H
.
PrintBuffer()
, PrintChar()
and PrintFormat()
, which replace
POSIX
functions like
fputchar()
,
printf()
,
putch()
,
puts()
,
putw()
etc., write
ASCII
in
ANSI
consoleprograms and UTF-16LE in Unicode
consoleprograms to their (redirected)
standard outputand
standard error.
Note: use the format specifiers %hc
and %hs
to print
ASCII
characters and character strings from
Unicode
console
programs, and the format specifiers %lc
alias %wc
and %ls
alias %ws
to print
UTF-16LE
characters and character strings from
ANSI
console
programs.
Note: in order to prevent a mix of
ASCII
and
UTF-16LE
which may be rendered as
mojibake
, in
ANSI
console
programs the
Unicode
functions PrintBufferW()
, PrintCharW()
and
PrintFormatW()
, and in
Unicode
console
programs the
ANSI
functions PrintBufferA()
, PrintCharA()
and
PrintFormatA()
, write nothing when their output is
redirected to a file, but return FALSE
and yield
Win32 error code 1288 alias
ERROR_INVALID_CRUNTIME_PARAMETER
instead.
NOMSVCRT.H
and the object library
NOMSVCRT.LIB
have the following limitations:
Windows’
Structured Exception Handling
with the keywords
__try
,
__except
,
__finally
and __leave
is supported only for the
AMD64 alias x64 processor architecture.
Neither
runtime checks
,
i.e. the compiler switches /RTC1
, /RTCc
,
/RTCs
and /RTCu
, nor
global initialisers
are supported.
The functions DebugFormat()
and
PrintFormat()
truncate their output to 1024
(ASCII
or
Unicode®)
characters, support 64-bit integers only with the (undocumented)
%…I64…
instead of the
%…ll…
argument length modifier,
don’t support the right alignment alias sign conversion flag
%+…
as well as the space conversion flag
% …
, and don’t support floating-point
conversion specifiers %…a
,
%…A
, %…e
,
%…E
, %…f
,
%…F
, %…g
,
%…G
at all.
Note: these limitations originate from the
Win32 functions
wsprintf()
and
wvsprintf()
.
Note: both functions also support the undocumented
%…I32…
argument length modifier.
The functions PrintBuffer()
, PrintChar()
and PrintFormat()
are supported only in console
programs.
Note: this limitation is imposed by the design of
Windows and explained in the
MSDN article
Creation of a Console
and the
MSKB
article
105305.
kludgeprints IEEE 754 double-precision floating-point numbers (almost) like the
%a
, %A
, %g
and
%G
conversion specifiers:
// Copyright © 2004-2024, Stefan Kanthak <stefan.kanthak@nexgo.de>
// Minimalist Win32 Runtime Library for Microsoft C Compiler 20xy
#include <windows.h>
#include <nomsvcrt.h>
int kludge(char *string, double number)
{
// see <https://msdn.microsoft.com/en-us/library/0b34tf65.aspx>
union _real8
{
// binary64 = (-1)**sign * significand * 2**(exponent - 1023)
//
// 53-bit significand is 0.fraction if 0 = exponent,
// 1.fraction if 0 < exponent < 2047,
// 1.anything if exponent = 2047
double binary64;
struct _IEEE_754_DOUBLE_PRECISION
{
unsigned long long fraction : 52;
unsigned long long exponent : 11;
unsigned long long sign : 1;
};
} real8 = {number};
char decimal[25];
dtostr(number, decimal);
return PrintFormat(STDOUT, "%s = %c0x%c.%013I64Xp%d\t= %s\n",
string,
real8.sign ? '-' : '+', real8.exponent ? '1' : '0', real8.fraction, real8.exponent ? (int) real8.exponent - 1023 : 1 - 1023,
decimal);
}
#define BIG (1.0e308)
#define INFINITY (1.0e308 + 1.0e308)
const double between = -4503599627370495.5; // = 2**52 - 1 / 2
const double big = BIG;
const double denormal = -4.940656458412465441765687928682213724e-324; // = 2**-1074
const double e = +2.718281828459045235360287471352662498;
const double epsilon = -2.220446049250313080847263336181640625e-16; // = 2**-52
const double indefinite = INFINITY * 0.0;
const double infinity = INFINITY;
const double maximum = +1.797693134862315708145274237317043568e+308; // = 2**+1024 * (1 - 2**-53)
const double minimum = -2.225073858507201383090232717332404064e-308; // = 2**-1022
const double null = BIG / INFINITY;
const double omicron = +9.999999999999998889776975374843459576e-1; // = 1 - 2**-53
const double pi = +3.141592653589793238462643383279502884;
const double ypsilon = +4503599627370496.0; // = 2**52
const double zero = -0.0;
int main(void)
{
double eps;
double max;
double min;
double nan = zero / zero;
double yps;
double overflow = 1.0;
double underflow = 1.0;
do { // compute 'machine epsilon'
eps = underflow;
underflow /= 2.0;
} while (underflow + 1.0 != 1.0);
do { // compute 'machine minimum'
min = underflow;
underflow /= 2.0;
} while (underflow > 0.0);
do { // compute 'machine ypsilon'
yps = overflow;
overflow *= 2.0;
} while (overflow + 1.0 != overflow);
overflow -= 1.0;
do { // compute 'machine maximum'
max = overflow;
overflow *= 2.0;
} while (overflow < INFINITY);
kludge("-4503599627370495.5", between);
kludge(" 1.0e308", big);
kludge(" -denormal", denormal);
kludge(" e", e);
kludge(" -epsilon", epsilon);
kludge(" indefinite", indefinite);
kludge(" +infinity", infinity);
kludge(" -infinity", big - infinity);
kludge(" machine epsilon", eps);
kludge(" machine maximum", max);
kludge(" machine minimum", min);
kludge(" machine ypsilon", yps);
kludge(" maximum", maximum);
kludge(" -minimum", minimum);
kludge(" nan", nan);
kludge(" null", null);
kludge(" omicron", omicron);
kludge(" overflow", overflow);
kludge(" pi", pi);
kludge(" underflow", underflow);
kludge(" ypsilon", ypsilon);
kludge(" -0.0", zero);
return indefinite == indefinite;
}
This program printsthe following console output:
-4503599627370495.5 = -0x1.FFFFFFFFFFFFFp51 = -4503599627370495.5 1.0e308 = +0x1.1CCF385EBC8A0p1023 = 1e+308 -denormal = -0x0.0000000000001p-1022 = -5e-324 e = +0x1.5BF0A8B145769p1 = 2.718281828459045 -epsilon = -0x1.0000000000000p-52 = -2.220446049250313e-16 indefinite = -0x1.8000000000000p1024 = ind +infinity = +0x1.0000000000000p1024 = inf -infinity = -0x1.0000000000000p1024 = -inf machine epsilon = +0x1.0000000000000p-52 = 2.220446049250313e-16 machine maximum = +0x1.FFFFFFFFFFFFFp1023 = 1.7976931348623157e+308 machine minimum = +0x0.0000000000001p-1022 = 5e-324 machine ypsilon = +0x1.0000000000000p52 = 4503599627370496 maximum = +0x1.FFFFFFFFFFFFFp1023 = 1.7976931348623157e+308 -minimum = -0x1.0000000000000p-1022 = -2.2250738585072014e-308 nan = -0x1.8000000000000p1024 = ind null = +0x0.0000000000000p-1022 = 0 omicron = +0x1.FFFFFFFFFFFFFp-1 = 0.9999999999999999 overflow = +0x1.0000000000000p1024 = inf pi = +0x1.921FB54442D18p1 = 3.141592653589793 underflow = +0x0.0000000000000p-1022 = 0 ypsilon = +0x1.0000000000000p52 = 4503599627370496 -0.0 = -0x0.0000000000000p-1022 = -0Note: printing the special floating-point values
indefinite,
±infinity,
±0, quiet and signaling NANs as the character strings ind or nan(ind), +inf, -inf, +0, -0, nan and nan(snan) respectively is left as an exercise to the reader.
NOMSVCRT.H
and the object library
NOMSVCRT.LIB
implement the following helper routines,
internal functions
and
intrinsics
supported and used by Microsoft’s
Visual C compilers.
mainCRTStartup()
, wmainCRTStartup()
,
WinMainCRTStartup()
, wWinMainCRTStartup()
and
_DllMainCRTStartup()
call the conventional main()functions
main()
,
wmain()
,
WinMain()
,
wWinMain()
and
DllMain()
respectively.
Note: their command line processing and argument
splitting is feature bug-compatible to the
MSVCRT
runtime libraries and the Win32 function
CommandLineToArgvW()
:
an unpaired double quote " neither aborts nor yields a
Win32 error code like 160 alias
ERROR_BAD_ARGUMENTS
or 1639 alias
ERROR_INVALID_COMMAND_LINE
,
it is but (silently) closed at the end of the command line!
Note: when
STDOUT or
STDERR is redirected to
an empty (new) file, wmainCRTStartup()
, the startup
routine for
Unicode
console
programs, writes a
Unicode
BOM.
Note: when executed in a process with an own
console
window, the console
program startup routines
mainCRTStartup()
and wmainCRTStartup()
wait for a keypress before they exit and the console
window
closes; to indicate this wait state they beep once and flash the
title bar of their console
window after the
main()
respectively the
wmain()
function returns to the startup routine.
Note: the startup routines are implemented for all processor architectures supported by Windows NT.
_alloca()
,
_chkstk()
and
__security_check_cookie()
.
Note: contrary to the stack allocation routines
shipped with the
MSVCRT
runtime libraries for the I386 alias x86
processor architecture,
_alloca()
and
_chkstk()
don’t touch already committed stack pages.
Note: the
_alloca()
and
_chkstk()
functions are implemented only for the I386 alias
x86 and the AMD64 alias x64
processor architecture.
Note: the
/GS
runtime check routines are implemented for all processor
architectures supported by Windows NT; they raise an
exception with
NTSTATUS
0xC0000409
alias STATUS_STACK_BUFFER_OVERRUN
upon detection of a
corrupted stack cookie
.
Note: Windows’ module loader
overwrites the default stack cookie
(0xBB40E64E = 3141592654 = π×109
for 32-bit execution environment,
0x00002B992DDFA232 = π×1018÷216
for 64-bit execution environment) of
DLLs since
Windows XP SP2
and that of applications since Windows 10 with a
random
value.
_alldiv()
,
_alldvrm()
,
_allmul()
,
_allrem()
, _allshl()
and
_allshr()
are called for signed 64-bit integer
arithmetic and shift operations on the I386 alias
x86 processor architecture; the additional functions
_allabs()
, _allcmp()
,
_allneg()
, _allrol()
,
_allror()
and _allsgn()
are provided just
for fun.
Note: −263÷−1 raises no integer overflow exception, but returns −263!
Note: measured on processors of the Intel® Core™i family, the signed 64÷64-bit division routines are about 7 to 11 times faster than those supplied in the MSVCRT runtime libraries, and from about 2 times to just slightly slower than native signed 128÷64-bit division in the 64-bit execution environment; 64×64-bit multiplication is about 4 times slower than native 64×64-bit multiplication in the 64-bit execution environment.
The functions
Int32x32To64()
,
Int32x32To64Div32()
alias __emuldiv()
,
Int32x32To64Rem32()
alias __emulmod()
,
Int64Div32()
alias __ediv()
and
Int64Rem32()
alias __emod()
complement
the
__emul()
intrinsic; they are defined as
__inline
inline functions
in the header file NOMSVCRT.H
and implemented only for
the I386 alias x86 processor
architecture.
Int64ShraMod32()
_aulldiv()
,
_aulldvrm()
, _aullrem()
and
_aullshr()
are called for unsigned 64-bit integer
arithmetic and shift operations on the I386 alias
x86 processor architecture; the additional functions
_aullcmp()
, _aullgcd()
,
_aullmul()
, _aullrol()
,
_aullror()
and _aullshl()
are provided
just for fun.
Note: measured on processors of the Intel® Core™i family, the unsigned 64÷64-bit division routines are about 7 to 11 times faster than those supplied in the MSVCRT runtime libraries, and from less than 2 times slower to even 20 % faster than native unsigned 128÷64-bit division in the 64-bit execution environment; 64×64-bit multiplication is about 4 times slower than native 64×64-bit multiplication in the 64-bit execution environment.
The functions
UInt32x32To64()
,
UInt32x32To64Div32()
alias __emuldivu()
,
UInt32x32To64Rem32()
alias __emulmodu()
,
UInt64Div32()
alias __edivu()
and
UInt64Rem32()
alias __emodu()
complement
the
__emulu()
intrinsic; they are defined as
__inline
inline functions
in the header file NOMSVCRT.H
and implemented only for
the I386 alias x86 processor
architecture.
Int64ShllMod32()
Int64ShrlMod32()
_div64()
and
_udiv64()
,
since Visual C 2019 available as
intrinsics
only for the I386 alias x86 and the
AMD64 alias x64 processor architecture,
are implemented for the I386 alias x86
and the AMD64 alias x64 processor
architecture.
__mulh()
alias
MultiplyHigh()
,
__umulh()
alias
UnsignedMultiplyHigh()
,
_mul128()
alias
Multiply128()
and
_umul128()
alias
UnsignedMultiply128()
,
available as
intrinsics
only for the AMD64 alias x64 processor
architecture, are implemented for the I386 alias
x86 processor architecture.
_div128()
and
_udiv128()
,
since Visual C 2019 available as
intrinsics
only for the AMD64 alias x64 processor
architecture, are implemented for the I386 alias
x86 and the AMD64 alias x64
processor architecture; they complement the functions and intrinsics
_mul128()
alias
Multiply128()
and
_umul128()
alias
UnsignedMultiply128()
.
Note: measured on processors of the
Intel® Core™2 family,
the _udiv128()
function runs in the 32-bit execution
environment about 5 % to 50 % slower than the
_udiv128()
intrinsic in the 64-bit execution environment.
__shiftleft128()
alias
ShiftLeft128()
and
__shiftright128()
alias
ShiftRight128()
,
available as
intrinsics
only for the AMD64 alias x64 processor
architecture, are implemented for all (other) processor
architectures supporting shift operations on 64-bit integers.
The functions
__rotateleft128()
and __rotateright128()
complement the functions and intrinsics
__shiftleft128()
and
__shiftright128()
;
they are defined as
__inline
inline functions
for all processor architectures supporting shift operations on
64-bit integers.
Note: on the I386 alias x86 and the AMD64 alias x64 processor architecture, shift and rotation counts from 0 to 64 are supported and performed modulo 64; on other processor architectures shift and rotation counts from 1 to 63 are supported.
_CIacos()
,
_CIasin()
,
_CIatan()
,
_CIatan2()
,
_CIcos()
,
_CIcosh()
,
_CIexp()
,
_CIfmod()
,
_CIlog()
,
_CIlog10()
,
_CIpow()
,
_CIsin()
,
_CIsinh()
,
_CIsqrt()
,
_CItan()
,
_CItanh()
,
_ftol()
,
_ftol2()
,
_ftol2_sse()
,
acos()
,
acosh()
,
asin()
,
asinh()
,
atan()
,
atan2()
,
atanh()
,
cbrt()
,
ceil()
,
copysign()
,
cos()
,
cosh()
,
exp()
,
exp2()
,
expm1()
,
fabs()
,
fdim()
,
floor()
,
fmax()
,
fmin()
,
fmod()
,
frexp()
,
hypot()
,
ilogb()
,
ldexp()
,
logb()
,
log()
,
log1p()
,
log2()
,
log10()
,
lrint()
,
llrint()
,
modf()
,
nextafter()
,
pow()
,
remainder()
,
remquo()
,
rint()
,
round()
,
scalbn()
,
_scalb()
,
sin()
,
sinh()
,
sqrt()
,
tan()
,
tanh()
and
trunc()
,
plus acot()
, acot2()
,
acoth()
, cot()
, coth()
,
exp10()
, frexp10()
,
ldexp10()
, pown()
and
signbit()
.
Note: the floating-point routines support only the
double-precision floating-point data type double
.
Note: the floating-point routines are implemented only for the I386 alias x86 processor architecture; they use the algebraic, arithmetic, transcendental and trigonometric functions of the processor’s builtin IEEE 754 FPU.
Note: the (almost) undocumented internal
functions _CI*()
implement the respective
intrinsics
on the I386 alias x86 processor
architecture; calls to these functions are generated when the
command line switches
/fp:fast
or
/fp:precise
and
/Oi
or
/O2
but not
/Qfast_transcendentals
are used, or equivalent
#pragma
directives are given.
alloc_text
pragma
auto_inline
pragma
bss_seg
pragma
check_stack
pragma
code_seg
pragma
comment
pragma
component
pragma
conform
pragma
const_seg
pragma
data_seg
pragma
deprecated
pragma
detect_mismatch
pragma
endregion
pragma
fenv_access
pragma
float_control
pragma
fp_contract
pragma
function
pragma
hdrstop
pragma
include_alias
pragma
init_seg
pragma
inline_depth
pragma
inline_recursion
pragma
intrinsic
pragma
loop
pragma
make_public
pragma
managed
pragma
message
pragma
omp
pragma
once
pragma
optimize
pragma
pack
pragma
pointers_to_members
pragma
pop_macro
pragma
push_macro
pragma
region
pragma
runtime_checks
pragma
section
pragma
setlocale
pragma
strict_gs_check
pragma
unmanaged
pragma
vtordisp
pragma
warning
pragma
dtostr()
, based on Florian Loitsch’
Grisu
algorithm, converts a double-precision floating-point number into
its (almost always shortest) printable decimal representation, like
the %g
and %G
conversion specifiers
of the
printf()
function.
strtod()
converts an
ASCII
character string
[ ‹white space› ] [{ + | - }] ‹decimal digit› … [ . [ ‹decimal digit› … ]] [{ e | E } [{ + | - }] ‹decimal digit› … ],
[ ‹white space› ] [{ + | - }] [ ‹decimal digit› … ] . ‹decimal digit› … [{ e | E } [{ + | - }] ‹decimal digit› … ],
[ ‹white space› ] [{ + | - }] 0 { x | X } ‹hexadecimal digit› … [ . [ ‹hexadecimal digit› … ]] [{ p | P } [{ + | - }] ‹decimal digit› … ],
[ ‹white space› ] [{ + | - }] 0 { x | X } [ ‹hexadecimal digit› … ] . ‹hexadecimal digit› … [{ p | P } [{ + | - }] ‹decimal digit› … ]
or
[ ‹white space› ] [{ + | - }] { infinity | INFINITY | inf | INF | nan | NAN }
into a double-precision floating-point number.
Note: the behaviour is undefined for more than 231−1 significant or insignificant mantissa digits!
wcstod()
converts an
Unicode
character string
[ ‹white space› ] [{ + | - }] ‹decimal digit› … [ . [ ‹decimal digit› … ]] [{ e | E } [{ + | - }] ‹decimal digit› … ],
[ ‹white space› ] [{ + | - }] [ ‹decimal digit› … ] . ‹decimal digit› … [{ e | E } [{ + | - }] ‹decimal digit› … ],
[ ‹white space› ] [{ + | - }] 0 { x | X } ‹hexadecimal digit› … [ . [ ‹hexadecimal digit› … ]] [{ p | P } [{ + | - }] ‹decimal digit› … ],
[ ‹white space› ] [{ + | - }] 0 { x | X } [ ‹hexadecimal digit› … ] . ‹hexedecimal digit› … [{ p | P } [{ + | - }] ‹decimal digit› … ]
or
[ ‹white space› ] [{ + | - }] { infinity | INFINITY | inf | INF | nan | NAN }
into a double-precision floating-point number.
Note: the behaviour is undefined for more than 231−1 significant or insignificant mantissa digits!
itoa()
,
ltoa()
,
lltoa()
,
ultoa()
and ulltoa()
convert a signed or unsigned 32-bit or
64-bit integer number into its printable representation to bases
from 2 to 36.
The functions ltostr()
, ultostr()
,
lltostr()
and ulltostr()
convert a signed
or unsigned 32-bit or 64-bit integer number into its (shortest)
printable decimal representation.
itow()
,
ltow()
,
lltow()
,
ultow()
and ulltow()
convert a signed or unsigned 32-bit or
64-bit integer number into its printable representation to bases
from 2 to 36.
strtol()
and
strtoll()
convert an
ASCII
character string
[ ‹white space› ] [{ + | - }] [ 0 [{ b | B | x | X }]] { ‹decimal digit› | ‹latin letter› } …
into a signed 32-bit or 64-bit integer number.
The functions
strtoul()
and
strtoull()
convert an
ASCII
character string
[ ‹white space› ] [ + ] [ 0 [{ b | B | x | X }]] { ‹decimal digit› | ‹latin letter› } …
into an unsigned 32-bit or 64-bit integer number.
Note:
strtoul()
and
strtoull()
support only positive values, they don’t accept a −
sign!
wcstol()
and
wcstoll()
convert an
Unicode
character string
[ ‹white space› ] [{ + | - }] [ 0 [{ b | B | x | X }]] { ‹decimal digit› | ‹latin letter› } …
into a signed 32-bit or 64-bit integer number.
The functions
wcstoul()
and
wcstoull()
convert an
Unicode
character string
[ ‹white space› ] [ + ] [ 0 [{ b | B | x | X }]] { ‹decimal digit› | ‹latin letter› } …
into a unsigned 32-bit or 64-bit integer number.
Note:
wcstoul()
and
wcstoull()
support only positive values, they don’t accept a −
sign!
strcat()
,
strchr()
,
strcmp()
,
strcoll()
,
strcpy()
,
strcspn()
,
strlen()
,
strncat()
,
strncmp()
,
strnset()
,
strpbrk()
,
strrchr()
,
strrev()
,
strset()
,
strspn()
,
strstr()
,
strtok()
,
strxfrm()
and
_strset()
,
plus strtok_r()
.
Note: the ASCII character string handling routines are implemented only for the I386 alias x86 and the AMD64 alias x64 processor architecture.
wcscat()
,
wcschr()
,
wcscmp()
,
wcscoll()
,
wcscpy()
,
wcscspn()
,
wcslen()
,
wcsncat()
,
wcsncmp()
,
wcsnset()
,
wcspbrk()
,
wcsrchr()
,
wcsrev()
,
wcsset()
,
wcsspn()
,
wcsstr()
,
wcstok()
,
wcsxfrm()
and
_wcsset()
,
plus wcstok_r()
;
Note: the Unicode character string handling routines are implemented only for the I386 alias x86 and the AMD64 alias x64 processor architecture.
isasciiA()
alias
isascii()
,
isalnumA()
alias
isalnum()
,
isalphaA()
alias
isalpha()
,
isblankA()
alias
isblank()
,
iscntrlA()
alias
iscntrl()
,
isdigitA()
alias
isdigit()
,
isgraphA()
alias
isgraph()
,
islowerA()
alias
islower()
,
isprintA()
alias
isprint()
,
ispunctA()
alias
ispunct()
,
isspaceA()
alias
isspace()
,
isupperA()
alias
isupper()
,
and isxdigitA()
alias
isxdigit()
are defined as
__inline
inline functionsin the header file
NOMSVCRT.H
.
isasciiW()
alias
iswascii()
,
isalnumW()
alias
iswalnum()
,
isalphaW()
alias
iswalpha()
,
isblankW()
alias
iswblank()
,
iscntrlW()
alias
iswcntrl()
,
isdigitW()
alias
iswdigit()
,
isgraphW()
alias
iswgraph()
,
islowerW()
alias
iswlower()
,
isprintW()
alias
iswprint()
,
ispunctW()
alias
iswpunct()
,
isspaceW()
alias
iswspace()
,
isupperW()
alias
iswupper()
,
and isxdigitW()
alias
iswxdigit()
are defined as
__inline
inline functionsin the header file
NOMSVCRT.H
.
snprintf()
,
swprintf()
,
vsnprintf()
and
vswprintf()
are available with the following deviations and limitations:
%d
,
%i
,
%u
,
%o
,
%x
and
%X
support the
size and type modifiers
hh
for the argument types
signed char
and unsigned char
,
h
for the argument types
signed short int
and
unsigned short int
,
j
for the argument types
signed long long int
and
unsigned long long int
,
l
for the argument types
signed long int
and
unsigned long int
,
ll
for the argument types
signed long long int
and
unsigned long long int
,
t
for the argument type
ptrdiff_t
,
z
for the argument type size_t
,
signed int
and
unsigned int
.
%n
supports the size and type modifiers of the integer conversions;
%p
and
%P
support
neither size nor type modifiers;
%a
and
%A
are supported;
%e
and
%E
are supported, but print the
exponent without leading zeroes;
%f
,
%g
,
%F
and
%G
are not supported;
%c
and
%s
support the size and type
modifiers
h
for the argument types
signed char
, unsigned char
,
signed char *
and unsigned char *
;
l
for the argument types
signed wchar_t
, unsigned wchar_t
,
signed wchar_t *
and unsigned wchar_t *
;
char
and
char *
when used with the narrowalias ANSI variants of these functions, respectively
wchar_t
and
wchar_t *
when used with their widealias UTF-16LE variants.
%C
and
%S
have the opposite meaning:
they are equivalent to %hc
respectively
%hs
when used with the widealias UTF-16LE variants of these functions, and equivalent to
%lc
respectively %ls
when used with the narrowalias ANSI variants of these functions.
%c
and
%C
are equivalent to the character
string conversions %s
and
%S
with their
character argument as first element of the character string argument
followed by the terminating NUL
character, i.e. a
NUL
character is handled like an empty character string
and not printed!
Note: the size modifiers
w
, I32
and I64
are not supported!
The functions
sscanf()
,
swscanf()
,
vsscanf()
and
vswscanf()
are available with the following limitations:
%a
,
%e
,
%f
,
%g
,
%A
,
%E
,
%F
and
%G
don’t support an input
field width;
%n
,
%c
,
%s
,
%[…]
,
%p
,
%a
,
%e
,
%f
,
%g
,
%A
,
%E
,
%F
and
%G
don’t support an
output size or type modifier;
%[…]
does not support ranges, i.e. %[a-z]
matches the three
characters a
,
-
and
z
verbatim;
%c
,
%s
,
%[…]
is char *
with the
ASCII
functions
sscanf()
and
vsscanf()
,
and wchar_t *
alias unsigned short *
with
the
Unicode
functions
swscanf()
and
vswscanf()
;
%n
conversion is
int *
;
%p
conversion is void **
;
%a
,
%e
,
%f
,
%g
,
%A
,
%E
,
%F
and
%G
is double *
;
%d
,
%i
,
%u
,
%o
,
%x
and
%X
support the
output size and type modifiers
hh
for the output argument types
signed char *
and unsigned char *
,
h
for the output argument types
signed short int *
and
unsigned short int *
,
j
for the output argument types
signed long long int *
and
unsigned long long int *
,
l
for the output argument types
signed long int *
and
unsigned long int *
,
ll
for the output argument types
signed long long int *
and
unsigned long long int *
,
t
for the output argument type
ptrdiff_t *
,
z
for the output argument type
size_t *
,
signed int *
and unsigned int *
.
I64
is not
supported!
...
...
...
DebugFormat()
, PrintBuffer()
,
PrintChar()
, PrintFormat()
and
PrintString()
.
Print*()
functions return a non-zero value on
success; on failure they return 0 and a Win32 error
code for retrieval through the Win32 function
GetLastError()
.
Last-Error Code
Note: these functions are available for ASCII and Unicode; their prototypes follow the conventions of the Windows SDK.
Note: the functions PrintBuffer()
,
PrintChar()
and PrintFormat()
are
supported only in console
programs.
Note: in order to prevent a mix of
ASCII
and
UTF-16LE
which may be rendered as
mojibake
, in
ANSI
console
programs the
Unicode
functions PrintBufferW()
, PrintCharW()
and PrintFormatW()
, and in
Unicode
console
programs the
ANSI
functions PrintBufferA()
, PrintCharA()
and PrintFormatA()
, write nothing when their output is
redirected to a file, but return FALSE
and yield
Win32 error code 1288 alias
ERROR_INVALID_CRUNTIME_PARAMETER
instead.
Note: the functions DebugFormat()
and PrintFormat()
truncate their output to 1024
(ASCII
or
Unicode)
characters, support 64-bit integers only with the (undocumented)
%…I64…
instead of the
%…ll…
argument length modifier,
don’t support the right alignment alias sign conversion flag
%+…
as well as the space conversion flag
% …
, and don’t support floating-point
conversion specifiers %…a
,
%…A
, %…e
,
%…E
, %…f
,
%…F
, %…g
,
%…G
at all.
memchr()
,
memcmp()
,
memcpy()
,
memmove()
,
memset()
,
memmem()
plus memswap()
, and
wmemchr()
,
wmemcmp()
,
wmemcpy()
,
wmemmove()
,
wmemset()
,
wmemmem()
plus wmemswap()
.
lmemchr()
, lmemcmp()
,
lmemcpy()
, lmemmove()
,
lmemset()
plus lmemswap()
, and
llmemchr()
, llmemcmp()
,
llmemcpy()
, llmemmove()
,
llmemset()
plus llmemswap()
.
Note: for processor architectures other than
I386 alias x86 and AMD64
alias x64, only the memmem()
and
wmemmem()
functions are implemented.
Note: the lmem*()
functions are
implemented only for the I386 alias x86
and the AMD64 alias x64 processor
architecture.
Note: the llmem*()
functions are
implemented only for the AMD64 alias x64
processor architecture.
htonll()
,
htonl()
,
htons()
,
ntohll()
,
ntohl()
,
ntohs()
and
swab()
.
abs()
,
labs()
,
llabs()
,
max()
, lmax()
, llmax()
,
min()
, lmin()
, llmin()
,
sgn()
,
lsgn()
,
llsgn()
,
lzcnt32()
,
lzcnt64()
,
parity8()
, parity16()
,
parity32()
, parity64()
,
popcnt32()
,
popcnt64()
,
rev8()
,
rev16()
,
rev32()
,
rev64()
,
sqrt32()
,
sqrt64()
,
tzcnt32()
and
tzcnt64()
.
Note: most of these functions are defined as
__inline
inline functions
in the header file NOMSVCRT.H
.
Note: the functions
lzcnt32()
and
lzcnt64()
don’t use
the
__lzcnt()
intrinsics and are thus available on all processors.
Note: unlike the
PopulationCount64()
function defined in the header file WINNT.H
of recent
Windows
SDKs, the
functions popcnt32()
and
popcnt64()
don’t use the
__popcnt()
intrinsics and are thus available on all processors.
Note: the functions
tzcnt32()
and
tzcnt64()
don’t use
the
_tzcnt_u32()
and
_tzcnt_u64()
intrinsics and are thus available on all processors.
calloc()
,
free()
,
malloc()
and
realloc()
.
RandomNumber Generators
drbg32()
and
drbg64()
,
half32()
and
half64()
,
msqr32()
and
msqr64()
,
mwcg32()
and
mwcg64()
,
prng32()
and
prng64()
, plus
smcg32()
and
smcg64()
return uniform distributed unsigned integers in the range 0 to
232−1 and 264−1 respectively;
cntr32()
and
cntr64()
,
full32()
and
full64()
, plus
lfsr32()
and
lfsr64()
return
uniform distributed unsigned integers in the range 1 to
232−1 and 264−1 respectively.
Note: the generators are defined as
__inline
inline functions
in the header file NOMSVCRT.H
.
The generators provided by the functions
cntr32()
and
cntr64()
,
full32()
and
full64()
,
lfsr32()
and
lfsr64()
are
linear feedback shift registers alias Galois counters with period
lengths of 232−1 and 264−1
respectively, while the XorShift
generators
half32()
and
half64()
have
period lengths of 264−1 and 2128−1
respectively.
The deterministic random bit generator provided by the functions
drbg32()
and
drbg64()
applies a (two-round multiplicative) hash function to a (modular)
arithmetic progression alias Weyl sequence
; its period length
is 232 and 264 respectively.
Note: the (alias) name Weyl sequence
for a
(modular) arithmetic progression was coined by George Marsaglia
while introducing XorShift
pseudo-random number generators.
The pseudo-random number generator provided by the functions
msqr32()
and
msqr64()
combines John von Neumann’s middle-square
method with a
(modular) arithmetic progression alias Weyl sequence
to
overcome the well-known deficiencies of the middle-square
method, as originally devised by
Bernard Widynski,
following a proposal of
Richard Peirce Brent.
Note: contrary to his 32-bit only implementation,
which is not based on the middle-square
method, but combines a pure quadratic (non-linear) congruential
generator with a pure additive (linear) congruential generator and
an invertible mapping,
msqr32()
and
msqr64()
use
the true middle of the square instead of just its lower half and
perform a byte-swap instead of the rotation.
The pseudo-random number generator provided by the functions
mwcg32()
and
mwcg64()
is
George Marsaglia’s multiply-with-carry generator.
The pseudo-random number generator provided by the functions
prng32()
and
prng64()
is
Bob Jenkins’
small fast
generator.
The pseudo-random number generator provided by the functions
smcg32()
and
smcg64()
is a multiplicative (linear) congruential generator, invented by
Derrick Henry Lehmer, with scrambled output, as originally devised
by
Melissa O'Neill.
The following table shows the execution times of some of these functions on different 64-bit processors in clock cycles per item; the upper half for the 32-bit execution environment, the lower half for the 64-bit execution environment.
half32() |
half64() |
msqr32() |
msqr64() |
mwcg32() |
mwcg64() |
smcg32() |
smcg64() |
prng32() |
prng64() |
||
AMD® Ryzen™5 3600 | 4 | 12 | 14 | 15 | 3 | 10 | 9 | 16 | 5 | 22 | |
AMD® Ryzen™7 2700X | 4 | 13 | 14 | 9 | 4 | 12 | 9 | 20 | 5 | 26 | |
Intel Core i5-8400 | 6 | 10 | 13 | 12 | 7 | 16 | 9 | 16 | 6 | 20 | |
Intel Core i5-6600 | 5 | 9 | 12 | 11 | 6 | 15 | 8 | 15 | 6 | 19 | |
Intel Core i5-4670 | 6 | 9 | 13 | 14 | 7 | 18 | 9 | 17 | 5 | 20 | |
Intel Core™2 P8700 | 5 | 10 | 13 | 19 | 6 | 18 | 8 | 19 | 5 | 25 | |
Intel Core™2 Q8400 | 5 | 9 | 13 | 19 | 6 | 18 | 8 | 19 | 5 | 24 | |
Intel® Pentium®4 | |||||||||||
AMD® Ryzen™5 3600 | 3 | 4 | 6 | 9 | 3 | 3 | 4 | 5 | 4 | 4 | |
AMD® Ryzen™7 2700X | 3 | 5 | 3 | 7 | 2 | 4 | 3 | 6 | 2 | 4 | |
Intel Core i5-8400 | 4 | 6 | 5 | 10 | 3 | 5 | 3 | 6 | 3 | 6 | |
Intel Core i5-6600 | 4 | 6 | 5 | 10 | 3 | 5 | 3 | 6 | 3 | 6 | |
Intel Core i5-4670 | 3 | 5 | 5 | 8 | 2 | 4 | 3 | 6 | 2 | 5 | |
Intel Core™2 P8700 | 5 | 6 | 15 | 15 | 10 | 7 | 10 | 9 | 5 | 5 | |
Intel Core™2 Q8400 | 5 | 6 | 15 | 15 | 10 | 7 | 10 | 9 | 5 | 5 | |
Intel® Pentium®4 |
Note: the 64-bit pseudo-random number generators
drbg64()
,
msqr64()
,
prng64()
and
smcg64()
pass a full 32 TB run of
the
PractRand
test suite version 0.94.
makefile
NOMSVCRT.MAK
to build the object library NOMSVCRT.LIB
for the
I386 alias x86 processor architecture, the
optional iconfile
NOMSVCRT.ICO
to build the resourcefile
NOMSVCRT.RES
, the
headerfile
NOMSVCRT.H
,
and the
ANSI C
source file
NOMSVCRT.C
to build the sample Windows application
NOMSVCRT.EXE
,
the sample DLL
NOMSVCRT.DLL
,
and the sample consoleprogram
NOMSVCRT.COM
,
…
NOMSVCRT.EXE
,
the sample DLL
NOMSVCRT.DLL
,
and the sample consoleprogram
NOMSVCRT.COM
are
digitally signed
using a (self-issued)
X.509
leaf certificate
and
time stamped.
Download and install the (self-signed) X.509 root certificate to validate and verify the digital certificate and the signature.
Use the X.509 certificate to send S/MIME encrypted mail.
Note: email in weird format and without a proper sender name is likely to be discarded!
I dislike
HTML (and even
weirder formats too) in email, I prefer to receive plain text.
I also expect to see your full (real) name as sender, not your
nickname.
I abhor top posts and expect inline quotes in replies.
as iswithout any warranty, neither express nor implied.
cookiesin the web browser.
The web service is operated and provided by
Telekom Deutschland GmbH The web service provider stores a session cookie
in the web
browser and records every visit of this web site with the following
data in an access log on their server(s):