【发布时间】:2016-06-12 08:06:42
【问题描述】:
查看 C 标准库中的大多数函数,似乎缺少 const,通常更喜欢指定 const。
例如:
ctype.h/c
extern int isupper(int __c) __ATTR_CONST__;
extern int islower(int __c) __ATTR_CONST__;
extern int isdigit(int __c) __ATTR_CONST__;
为什么不用这些:
extern int isupper(const int __c) __ATTR_CONST__;
extern int islower(const int __c) __ATTR_CONST__;
extern int isdigit(const int __c) __ATTR_CONST__;
他们毕竟只观察参数:
int isupper(int c) {
return _pctype[c] & _UPPER;
}
int islower(int c) {
return _pctype[c] & _LOWER;
}
int isdigit(int c) {
return _pctype[c] & _DIGIT;
}
或者让我们在 string.c 中取一个函数:
void *memcpy(void *dest, const void *src, size_t count)
{
char *tmp = dest;
const char *s = src;
while (count--)
*tmp++ = *s++;
return dest;
}
为什么不:
void *memcpy(void *const dest, const void *const src, size_t count);
在这些地方排除 const 是有原因的吗?
以我展示的方式包含 const 会不会是错误的?
我认为由于历史原因,这些功能一直保持这种状态,
但我想我应该问一下,以防我错过了什么。
【问题讨论】:
-
您展示的
memcpy函数的实现是初学者如何做到的,它不是很优化,并且使用memcpy的程序的发布版本不会使用这种幼稚的实现(除非编译器标准库非常愚蠢)。至于字符分类“函数”,它们可能被实现为宏,因此不能具有 const 正确性。 -
@JoachimPileborg 好吧,不是我写的。这就是我新安装的 linux 发行版系统文件中的内容。
-
他暗示的是专业解决方案可能会利用处理器的全部复制能力。例如,他们可以使用
uint_fast8_t代替char,然后将count减少sizeof(uint_fast8_t)而不是1。我觉得奇怪的是,您会在Linux 中的某个地方找到这样一个幼稚的实现,memcpy通常会被集成在编译器中。 -
顺便说一句,正确的库实现也将使用
restrict指针。与“const 正确性”类似,每当您编写一个在两个内存位置之间进行复制的函数时,也存在“限制正确性”。 ISO C 要求 memcpy 具有以下定义:void *memcpy(void * restrict s1, const void * restrict s2, size_t n); -
我希望这个问题是关于像
char *strstr(const char *s1, const char *s2);这样在const char *s1中返回char *表单的函数。
标签: c string constants const-correctness ctype