我知道遗产始终是合理的,但是我想从MariaDB and see if I understand it enough to critique what's going on,来查看这个示例
static int show_open_tables(THD *, SHOW_VAR *var, char *buff) {
var->type = SHOW_LONG;
var->value = buff;
*((long *)buff) = (long)table_cache_manager.cached_tables();
return 0;
}
在这里,他们正在使用char*
,并将其写入var->value
which is also a char*
。然后,它们在buff
中强制将指针指向long并将其类型设置为SHOW_LONG
来指示它。
我想知道为什么他们为此使用char*
而不使用uintptr_t
-尤其是当他们强迫指向long和其他类型的指针时。
规范{-{1}}之前是否不使用uintptr_t
来实现C ++中的多态性?
答案 0 :(得分:2)
这里似乎有两个问题。所以我把答案分开了。
char*
使用char*
很好。字符类型(char
,signed char
和unsigned char
)由C和C ++标准专门处理。 C标准定义了以下用于访问对象的规则:
只能通过具有以下类型之一的左值表达式访问对象的存储值:
- 与对象的有效类型兼容的类型
- 与对象的有效类型兼容的类型的限定版本,
- 一种类型,它是与对象的有效类型相对应的有符号或无符号类型,
- 一种类型,它是与对象的有效类型的限定版本相对应的有符号或无符号类型,
- 在其成员(包括递归地包括子集合或包含的联盟的成员)中包括上述类型之一的集合或联合类型,或
- 一种字符类型。
这实际上意味着字符类型是标准最接近定义“字节”类型的字符(C ++ 17中的std::byte
仅定义为enum class byte : unsigned char {}
)
但是,按照上述规则,将char*
强制转换为long*
然后分配给它是不正确的(尽管通常在实践中可行)。应该使用memcpy
。例如:
long cached_tables = table_cache_manager.cached_tables();
memcpy(buf, &cached_tables, sizeof(cached_tables));
void*
也将是一个合理的选择。是否更好是一个意见的问题。我想说的最明确的选择是为char
添加一个类型别名,以传达使用它作为字节类型的意图(例如typedef char byte_t
)。不过,我想起了几个杰出的库示例,这些示例按原样使用char
作为字节类型。例如,Boost存储器映射的文件代码给出了char*
,leveldb使用std::string
作为字节缓冲区类型(大概是为了利用SSO)。
uinptr_t
: uintptr_t
是可选类型,定义为能够保存指针的无符号整数。如果要以整数存储指向对象的地址,则它是适合使用的类型。这不是在这里使用的合适类型。
答案 1 :(得分:0)
他们正在使用char *,并且正在将其写入var-> value,这也是char *。然后,他们将指针强制指向buff中的long,并将类型设置为SHOW_LONG来指示它。
或其他。该代码是可怕的。
我想知道为什么他们为什么要为此使用char *而不是uintptr_t?尤其是当他们强迫指向long和其他类型的指针时。
谁知道?谁知道他写的时候写的是什么?谁在乎?该代码是可怕的,我们当然不应该尝试从中学习。
规范pre-uintptr_t是否不将void *用于C ++中的多态?
是,现在仍然如此。 uintptr_t
的目的是定义一个足够容纳指针的整数类型。
我想从MariaDB中查看这个示例,看看我是否足够理解它来批评正在发生的事情
您可能对此有所保留,但我当然没有,那只是一个公然的谎言。这样做的方式(如果绝对需要)(显然)是:
static int show_open_tables(THD *, SHOW_VAR *var, long *buff) {
var->type = SHOW_LONG;
var->value = (char *) buff;
*buff = (long)table_cache_manager.cached_tables();
return 0;
}
那么至少它不再是定时炸弹了。
嗯,好吧,也许(只是也许)该函数在某个地方的分派表中使用,因此需要(除非您强制转换)具有特定的签名。如果是这样,我当然不会挖掘10,000行代码来找出(而且无论如何,我不能这样做,因为它使我的平板电脑崩溃了很长时间)。
但是,如果有的话,那只会使情况变得更糟。现在,定时炸弹已成为stealth bomber。无论如何,我不相信这是片刻。这只是一件危险的废话。