According to documentation, under /kernel mode:
You must explicitly define the
new()ordelete()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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With