当前位置: 首页 > 知识库问答 >
问题:

为什么指向int的指针转换为void*而指向函数的指针转换为bool?

林哲茂
2023-03-14

关于指针的转换,C草案标准(N3337)有以下内容:

4.10指针转换

2“指向cv的指针”类型的右值(其中T是对象类型)可以转换为“指向cv的指针无效”类型的右值将“指向cv的指针”转换为“指向cv的指针无效”的结果指向类型为T的对象所在的存储位置的起点,就好像该对象是类型为T的派生度最高的对象(1.8)(即,不是基类子对象)。

4.12布尔转换

1算术、枚举、指针或指向成员类型的指针的右值可以转换为布尔类型的右值。零值、空指针值或空成员指针值被转换为false;任何其他值都转换为true

基于上述情况,完全可以将函数指针或指向int的指针转换为void*以及bool。

但是,如果两者都可以选择,指针应该转换为哪个?

那么,为什么指向函数的指针转换为bool,指向int的指针转换为val*

计划:

#include <iostream>
using namespace std;

void foo(const void* ptr)
{
   std::cout << "In foo(void*)" << std::endl;
}

void foo(bool b)
{
   std::cout << "In foo(bool)" << std::endl;
}

void bar()
{
}

int main()
{
   int i = 0;
   foo(&bar);
   foo(&i);
   return 0;
}

输出,使用g 4.7.3:

In foo(bool)
In foo(void*)

共有1个答案

上官彬
2023-03-14

基于上述情况,完全可以将函数指针或指向int的指针转换为void*以及bool。

引号中指出,指向对象的指针可以转换为cv void*。函数不是对象,这将取消转换为cv void*的资格,只留下布尔值。

但是,如果两者都可以选择,指针应该转换为哪个?

它应该转换为const val*overbool。为什么?好吧,准备从重载分辨率(§13.3[over.match]/2)开始的旅程。当然,强调我的。

但是,一旦确定了候选函数和参数列表,最佳函数的选择在所有情况下都是相同的:

-首先,选择候选函数的子集(具有适当数量的参数并满足某些其他条件的函数)以形成一组可行函数(13.3.2)。

-然后,根据将每个参数与每个可行函数的相应参数相匹配所需的隐式转换序列(13.3.3.1),选择最佳可行函数。

让我们跳到§13.3.3.1[over.best.ics]/3,看看什么是隐式转换序列:

格式良好的隐式转换序列是以下形式之一:
-标准转换序列(13.3.3.11),
-用户定义的转换序列(13.3.3.12),或
-省略号转换序列(13.3.3.13)。

我们对标准转换序列感兴趣。让我们跳到标准转换序列(§13.3.3.1.1[超过ics.scs]):

1表12总结了第4条中定义的转换,并将其分为四个不相交的类别:左值转换、资格调整、晋升和转换。[注:这些类别与值类别、cv限定和数据表示正交:左值转换不会更改类型的cv限定或数据表示;限定调整不会更改类型的值类别或数据表示;升级和转换不会更改值类别或cv限定类型的。-结束注释]

2[注:如第4条所述,标准转换顺序要么是身份转换本身(即无转换),要么由其他四个类别的一到三个转换组成。

重要的部分在/2中。标准转换序列可以是单个标准转换。表12列出了这些标准转换,如下所示。请注意,指针转换和布尔转换都在其中。

从这里,我们学到了一些重要的东西:指针转换和布尔转换具有相同的排名。请记住,当我们进入排序隐式转换序列(§13.3.3.2[over.ics.rank])时。

看看/4,我们看到:

标准转换序列按其等级排序:精确匹配的转换比升级更好,升级的转换比转换更好。除非以下规则之一适用,否则具有相同秩的两个转换序列是无法区分的:

-不将指针、指向成员的指针或std::nullptr\t转换为bool的转换比这样的转换更好。

我们已经找到了一个非常明确的答案。好极了

 类似资料:
  • 一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似。我们可以把函数的这个首地址(或称入口地址)赋予一个 指针变量,使指针变量指向函数所在的内存区域,然后通过指针变量就可以找到并调用该函数。这种指针就是 函数指针。 函数指针的定义形式为: returnType (*pointerName)(param list); returnType

  • 在下面给出的代码中,我声明了一个指向int的指针,我们都知道memcpy返回一个指向目标字符串的空指针,所以如果ptr是指向int的指针,那么为什么printf(“%s”,ptr);是完全有效的,ptr毕竟不是指向char的指针。

  • 本文向大家介绍什么是指向指针的指针? 相关面试题,主要包含被问及什么是指向指针的指针? 时的应答技巧和注意事项,需要的朋友参考一下 指针指向的变量是一个指针,即具体内容为一个指针的值,是一个地址. 此时指针指向的变量长度也是4位.

  • GCC 8.2.1和MSVC 19.20编译以下代码,但Clang 8.0.0和ICC 19.0.1无法这样做。 Clang 8.0.0 的错误消息如下: 我注意到它在两种情况下可以用Clang编译: 从最后一个定义中删除括性 将线 替换为

  • 指针可以指向一份普通类型的数据,例如 int、double、char 等,也可以指向一份指针类型的数据,例如 int *、double *、char * 等。 如果一个指针指向的是另外一个指针,我们就称它为 二级指针,或者 指向指针的指针。 假设有一个 int 类型的变量 a,p1是指向 a 的指针变量,p2 又是指向 p1 的指针变量,它们的关系如下图所示: 将这种关系转换为C语言代码: 指针变

  • 6. 指向指针的指针与指针数组 指针可以指向基本类型,也可以指向复合类型,因此也可以指向另外一个指针变量,称为指向指针的指针。 int i; int *pi = &i; int **ppi = &pi; 这样定义之后,表达式*ppi取pi的值,表达式**ppi取i的值。请读者自己画图理解i、pi、ppi这三个变量之间的关系。 很自然地,也可以定义指向“指向指针的指针”的指针,但是很少用到: int