Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

/kernel mode in MSVC cl.exe allows new despite specifying user must explicitly define the operator

According to documentation, under /kernel mode:

You must explicitly define the new() or delete() operator. The compiler and runtime don't supply a default definition.

Yet, the following code compiles and runs fine without any error.

#include <iostream>

int main(){
    int* xyz = new int[10];
    std::cout<<"Hello!";
}

See godbolt link here: https://godbolt.org/z/96MTMcYeT

(Q1) Despite my not doing anything explicit regarding new(), why does the code compile correctly which seemingly goes against the official docs?

(Q2) In godbolt, is there a way to specify linker flags as opposed to just compile flags?

like image 709
One_Cable5781 Avatar asked Dec 14 '25 21:12

One_Cable5781


1 Answers

documentation is wrong. /kernel compiler option have no any effect to any form of new and delete . and compiler never supply a default implementation for any form of new and delete. so it must be implemented somewhere. in some .lib file wich you add to linker input or by your code.

why does the code compile correctly which seemingly goes against the official docs?

and why it must not compile ?? and even "official docs" not say that code must not compile. the compile recognize new and delete without external declarations.

another question is linking.

if you use code like this

    if (int* p = new int)
    {
        delete p;
    }

the copmiler probably implement new int as call to ??2@YAPEAX_K@Z and delete p as ??3@YAXPEAX_K@Z . and when you link - linker will be search for this 2 symbols in it input files (obj, lib) and if not found - you got error like this:

error LNK2001: unresolved external symbol "void * __cdecl operator new(unsigned __int64)" (??2@YAPEAX_K@Z)
error LNK2001: unresolved external symbol "void __cdecl operator delete(void *,unsigned __int64)" (??3@YAXPEAX_K@Z)

for resolve this error need or inclide lib file where it implemented ( msvcrt.lib) or implement this by self. as example

void* __cdecl operator new(size_t ByteSize)
{
    return LocalAlloc(0, ByteSize);
}

void __cdecl operator delete(void* Buffer,unsigned __int64)
{
    LocalFree(Buffer);
}

and how i say /kernel have no any effect here. with and without /kernel you need have implementation of ??2@YAPEAX_K@Z and so on.

in user mode we can use msvcrt.lib (or libcmt.lib ). if we build for kernel mode, we can not use msvcrt.lib and any wdk lib not provide implementation of ??2@YAPEAX_K@Z. so you need explicitly define the new() or delete() operators in this case. of course not with LocalAlloc but with ExAllocatePool (one of it variants).

and if we use `/kernel` compiler/linker switch this yet not mean that we build kernel mode binary. we can build and user mode binary with it. and visa versa - we can build kernel mode binary with or without /kernel switch

like image 80
RbMm Avatar answered Dec 17 '25 13:12

RbMm



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!