带有“const”关键字的 C 类型转换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3421540/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:48:18  来源:igfitidea点击:

C type casting with "const" keyword

c++ccastingconst

提问by Crend King

I usually use C type casting in C/C++ code. My question is, does adding the "const" keyword in the casting type mean anything to the result?

我通常在 C/C++ 代码中使用 C 类型转换。我的问题是,在转换类型中添加“const”关键字对结果有什么意义吗?

For example, I can think up several scenarios:

例如,我可以想出几个场景:

const my_struct *func1()
{
   my_struct *my_ptr = new my_struct;

   // modify member variables

   return (const my_struct *)my_ptr;
   // return my_instance;
}

In this one, the function constructs a new instance of a struct, and casting it to to a constant pointer, therefore caller will not be able to further modify its internal state except deleting it. Is the "const" casting required, recommended, or simply unnecessary, since either return statement works.

在这个函数中,函数构造了一个结构体的新实例,并将其强制转换为常量指针,因此调用者将无法进一步修改其内部状态,只能删除它。是否需要、推荐或根本不需要“const”转换,因为任一 return 语句都有效。

In this one, my_baseis the base class of my_derive.

在这个中,my_base是 的基类my_derive

const my_base *func2(const my_derive *my_ptr)
{
    return (const my_base *)my_ptr;
    // return (my_base *)my_ptr;
}

Since my_ptris already a const pointer, would casting it with (my_base *)involve a const_cast for removing const and another implicit const_cast when returning?

既然my_ptr已经是一个 const 指针,那么(my_base *)在返回时是否会涉及一个用于删除 const 的 const_cast 和另一个隐式 const_cast 的转换?

Is there any reason to add "const" to an integer function argument, since changing it never affect state outside the function?

是否有任何理由将“const”添加到整数函数参数中,因为更改它永远不会影响函数外部的状态?

void func3(const int i)
{
    // i = 0; is not allowed, but why, as it is harmless?
}

How about adding "const" when casting an integer? I think this should resemble func2().

在转换整数时添加“const”怎么样?我认为这应该类似于func2().

void func4(short i)
{
    const unsigned int j = (const unsigned int) i;
    // const unsigned int j = (unsigned int) i;
}

Correct me if I'm wrong. Considering type casting might be an FAQ, I'm not sure if this one duplicates with anything else. Thanks!

如果我错了纠正我。考虑到类型转换可能是常见问题解答,我不确定这是否与其他任何内容重复。谢谢!

回答by Kirill V. Lyadvinsky

Adding the constkeyword in the casting type means that the result will be constant. The following will not compile in C++ (in C it has no effect):

const在转换类型中添加关键字意味着结果将是常量。以下内容不会在 C++ 中编译(在 C 中无效):

int* x = (const int*)malloc(10); // cannot convert from 'const int *' to 'int *'

You really shouldn't use C type casting in your C++code. It is not safe and should be used only for compatibility with the legacy C code. You should use C++ casts instead.

你真的不应该在你的C++代码中使用 C 类型转换。它不安全,应仅用于与遗留 C 代码兼容。您应该改用 C++ 强制转换。

In cases as in func3usually constqualifier is not used. There's no big reason to add constqualifier to function argument if it has not pointer or not reference type. Consider the following:

func3通常情况下const不使用限定符。const如果函数参数没有指针或不是引用类型,则没有什么大的理由向函数参数添加限定符。考虑以下:

void func3(      TYPE i);  // no reason to use `const`
void func3(const TYPE& i); // use `const`, so as not to accidentally change `i`

When you assign lvalue to rvalue, as in func4, there's no need to explicitly specify the constqualifier in the cast expression. Lvalue-to-rvalue conversion will be performed implicitly according to the C++ Standard 4.1.

当您将左值分配给右值时,如在 中func4,无需const在强制转换表达式中显式指定限定符。左值到右值的转换将根据 C++ 标准 4.1 隐式执行。

回答by Anthony Williams

Adding constto a cast is just like adding constto any other type specifier --- the resulting object is const. what this means depends on the context. If you add constat the top level (e.g. const intor const fooor int* const, then you just have a constobject. In most cases this can be copied and assigned just like a non-constobject can (though there's a few exceptions, like std::auto_ptr).

添加const到强制转换就像添加const到任何其他类型说明符一样——结果对象是const. 这意味着什么取决于上下文。如果您const在顶层添加(例如const intorconst fooint* const,那么您只有一个const对象。在大多数情况下,这可以像非const对象一样复制和分配(尽管有一些例外,例如std::auto_ptr)。

If you add the constto a pointer then you can also add it to the pointed-to type. e.g. int * constis a constpointer to a plain int, whereas const int*or int const*is a plain pointer to a const int.

如果你把const加到一个指针上,那么你也可以把它加到被指向的类型上。egint * const是一个const指向plain的指针int,而const int*orint const*是一个指向a 的普通指针const int

int i;
int* p = (int* const) &i; // fine; top-level const not a problem
int* p2 = (int const*) &i; // error; pointed-to object is const, so this is preserved
int const* p3= (int const*) &i; // OK

constat the top level in a parameter declaration is just like declaring any other local variable const--- you cannot modify the named object within the function body. However, this constdoes not form part of the function type, so you can forward-declare the function without (with conforming compilers at least).

const在参数声明的顶层就像声明任何其他局部变量一样const——你不能在函数体内修改命名对象。但是,这const不构成函数类型的一部分,因此您可以在没有(至少使用符合标准的编译器)的情况下向前声明函数。

void func(int i); // forward-declare func
void func(const int i) // this matches the declaration
{
    // i is const here
}

This could be argued to be good style --- whether or not the variable is treated as constinside the function is an implementation detail so shouldn't be in the prototype. Within the definition, it follows the guideline of declaring something constif you don't intend to modify it.

这可以说是一种很好的风格——变量是否被视为const在函数内部是一个实现细节,所以不应该在原型中。在定义中,const如果您不打算修改它,它遵循声明某些内容的准则。

Using constelsewhere in the parameter declaration (e.g. as part of a pointer) does affect the function type, as with the casts.

const在参数声明的其他地方使用(例如作为指针的一部分)确实会影响函数类型,就像强制转换一样。

回答by Dani

In the first example returning non-const in a function that requires const will cat it again meaning that const matters, but you can't notice it because if it's not there it will be added.
In the second example it will be one cast maintaining const.
In third example it is disallowed because it is harmless: i will change for the rest of the function and unrecoverable.
Keep in mind that putting type into container not of it's type will cast it automaticllay same as int put in long field won't remain int.
You also have to remember that const means about the same as private or public to the assembler, which is nothing. The assembler code generated will not differ at all no matter where you put const and will run at same speed exacly.

在第一个示例中,在需要 const 的函数中返回非常量将再次对其进行处理,这意味着 const 很重要,但您不会注意到它,因为如果它不存在,它将被添加。
在第二个示例中,它将是一个保持常量的演员表。
在第三个示例中,它是不允许的,因为它是无害的:我将更改函数的其余部分并且不可恢复。
请记住,将类型放入容器中而不是它的类型将自动将其转换为与放入 long 字段中的 int 相同的类型不会保持为 int。
您还必须记住,对于汇编程序来说,const 的含义与 private 或 public 大致相同,这没什么。无论您将 const 放在哪里,生成的汇编代码都不会有所不同,并且会以完全相同的速度运行。