为什么operator new不强制将参数作为“const size_t”?

发布于 2024-11-25 18:55:42 字数 421 浏览 5 评论 0原文

没有在任何地方使用下面的东西,但这个问题仍然在我脑海中存在很长时间。

void* operator new (size_t size)
{
  // distort `size` to other value
  return malloc(size);
}

知道上述可能不是重载 new 的明确定义的行为(例如,如果 size 减小),为什么标准不强制编译器将其设为 <代码>void *运算符新(const size_t); ?

对于operatordelete也可以争论,它应该voidoperatordelete(void*const);(添加const以避免指针获取改变)。

Not using below thing anywhere but still this question was in my mind for long.

void* operator new (size_t size)
{
  // distort `size` to other value
  return malloc(size);
}

Having know that above may not be a well-defined behavior for overloaded new (say if the size is decreased), Why doesn't standard force compilers to make it as void* operator new (const size_t); ?

The same can be argued for operator delete also, where it should void operator delete (void* const); (adding const to avoid pointer getting changed).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

我们只是彼此的过ke 2024-12-02 18:55:42
void* operator new (const size_t n);
void* operator new (size_t n);

这两个是完全相同的operator new 声明。唯一的区别是,如果它是一个定义,则 n 将被允许或不允许在函数体内修改(这与调用者无关,因为参数是按值传递的)。由于这是一个实现细节,因此标准没有讨论它。

请记住,顶级 const 在函数声明中被忽略。它们仅在定义中相关。

void* operator new (const size_t n);
void* operator new (size_t n);

These two are completely identical declarations of operator new. The only difference is that if it were a definition, n would be or wouldn't be allowed to be modified inside the function body (which would be irrelevant to the caller, since the parameter is passed by value). Since that is an implementation detail, the standard doesn't talk about it.

Remember, top-level const's are ignored in function declarations. They're relevant only in definitions.

人生百味 2024-12-02 18:55:42

在这两种情况下,const std::size_t 和普通 std::size_t 的参数类型都是 std::size_t。标准规定,当处理声明中的函数签名(稍后的定义)时,const 将从类型中删除。具体的
段落位于 §8.3.5/3 中:

[...] 生成参数类型列表后,会对这些类型进行多次转换以确定函数类型。任何修改参数类型的 cv 限定符都会被删除。 [示例:类型 void()(const int) 变为 void()(int) —示例结束]

现在,在函数的定义中,const 确实具有您建议的效果:阻塞你不能修改参数。您可以使用 const std::size_t 参数自由地实现您的 operator new 。另一方面,强制执行基本上是没有用的。正如其他人提到的,参数是 const 的事实可以通过将其复制到不同的变量并使用该变量来破坏。当它不能给语言带来真正的价值时,向编译器添加额外的验证负担是没有意义的。

The type of the argument in both cases, const std::size_t and plain std::size_t is std::size_t. The standard dictates that when processing a function signature in a declaration (later on definitions), the const is dropped from the type. The specific
paragraph is in §8.3.5/3:

[...] After producing the list of parameter types, several transformations take place upon these types to determine the function type. Any cv-qualifier modifying a parameter type is deleted. [Example: the type void()(const int) becomes void()(int) —end example]

Now, in the definition of the function, the const does have the effect that you propose: blocking you from modifying the argument. You are free to implement your operator new with a const std::size_t argument. On the other hand, enforcing that would be basically useless. As others have mentioned, the fact that the argument is const can be subverted by copying it to a different variable and using that variable. There is no point in adding the extra burden of verification to the compilers when it does not add real value to the language.

土豪我们做朋友吧 2024-12-02 18:55:42

好吧,让我们假设它是 const:

void* operator new (const size_t size)
{
   size_t alteredSize = size;
   alteredSize += 10; // for whatever reason
   return malloc( alteredSize );
}

完全相同

void* operator new (size_t size)
{
   size += 10;
   return malloc( size );
}

这与复制到函数中的参数(按值传递)的 const ,但不强制使用该值 -该函数可以创建一个可写副本并更改该副本。

Okay, let's pretend it is const:

void* operator new (const size_t size)
{
   size_t alteredSize = size;
   alteredSize += 10; // for whatever reason
   return malloc( alteredSize );
}

which is completely the same as

void* operator new (size_t size)
{
   size += 10;
   return malloc( size );
}

const on parameters that are copied into the function (passed by value) doesn't enforce using that value - the function can create a writable copy and alter that copy.

卸妝后依然美 2024-12-02 18:55:42

非引用参数的常量性仅具有边际重要性。

这些标准从调用者的角度定义了“重要”的事情。

这些按值参数的常量不会也不能更改使用它们的任何代码。实施者可以照顾自己。

更新:如果你愿意,你可以这样写。

int f (const int);
int f (int) {return 0;}

int main () {
    int i;
    f (i);
}

我没有收到上述任何错误。继续并 const-ify 你的 size_t :-)

为了避免反对意见:这里 f 代表 operator new 或其他。所以我们有一个矛盾的声明/定义,但编译器不会抱怨。为什么?因为这并不重要。

Const-ness for non-reference arguments is of only marginal importance.

The standards defines "important" things from the point of view of the caller.

Constness of these by-value arguments does not and cannot change any code which uses them. The implementer can look after themselves.

Update: you can write it this way if you want.

int f (const int);
int f (int) {return 0;}

int main () {
    int i;
    f (i);
}

I didn't get any errors with the above. Go ahead and const-ify your size_t :-)

To anticipate an objection: here f stands-in for operator new or whatever. So we have a contradicting declaration/definition, yet the compiler doesn't complain. Why? Because it just doesn't matter.

霓裳挽歌倾城醉 2024-12-02 18:55:42

您已经在 operator new 上收到了许多好的答案。还有一个关于size 参数设置为 operator new const 的论点:重写实现很可能希望分配比请求更多的空间,例如至于cookie、保护词等。

对于删除操作符也有同样的争论,它应该 void 操作符删除 (void* const); (添加 const 以避免指针被更改)。

在大多数使用虚拟内存的现代操作系统上,free 不一定将分配的内存释放给操作系统。该内存很可能仍然位于程序的虚拟空间中。迂腐的覆盖者很可能希望在删除指向的内存之前用绝对垃圾填充它,以进一步使调用函数对该内存的后续使用无效。调用函数在删除指向的内存后不得使用它,那么为什么要使用不必要的限制来限制operator delete呢?

You have already received many good answers on operator new. One more argument for not making the size argument to operator new const: An overriding implementation may well want to allocate more space than was requested, such as for cookies, guard words, etc.

The same can be argued for operator delete also, where it should void operator delete (void* const); (adding const to avoid pointer getting changed).

On most modern operating systems that use virtual memory, free does not necessarily release the allocated memory to the OS. That memory may still well be in the program's virtual space. A pedantic overrider may well want to fill the pointed-to memory with absolute garbage prior to deleting it to further invalidate subsequent use of that memory by the calling function. The calling function must not use the pointed-to memory after having deleted it, so why hobble operator delete with an unneeded restriction?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文