我不清楚C23关于unsequenced项职能的工作草案的措辞.在其他属性中,unsequenced个函数必须为independent:
(6)对象X通过函数调用为observed
- (6.1)如果两者同步,
- (6.2)如果X对于呼叫不是本地的,
- (6.3)如果X具有在函数调用之前开始的生存期,以及
- (6.4)如果在呼叫期间对X的访问进行了排序;
调用前存储的最后一个值X(如果有的话)被称为调用观察到的值X.
函数指针值f是independent,如果
- (6.5)对于通过不基于该调用的参数的左值对f的某个调用观察到的任何对象X,则在同一程序执行期间对f的所有调用中对X的所有访问都遵循相同的值;
- (6.6)否则,如果访问基于指针参数,则应存在唯一的此类指针参数P,使得对X的任何访问都应访问基于P的左值.
如果派生的函数指针值是独立的,则函数定义是独立的.
-N3096 $6.7.12.7 p6,为提高可读性而重新格式化
我的问题是,像strlen
这样的函数是否可以是independent.请考虑以下最小实施:
size_t strlen(const char* s) {
size_t len = 0;
for (; *s; ++s) { ++len; }
return len;
}
首先,*s
是否被认为是基于参数的访问?我认为Access is是基于一个参数,即一个指针参数,所以只有(6.6)的限制是相关的.
然而,(6.6)可能是一个问题.请注意,(6.5)表示"在对f的所有调用中,所有访问都是X",而(6.6)表示"所有访问都是X",范围更广,也可能适用于函数外部的访问.那么,以下情况就是一个问题:
struct string {
char data[N];
} str;
// ...
strlen(str.data); // A
str = ...;
strlen(str.data); // B
并不是所有对str
的全局访问都通过唯一的指针参数s
到strlen
进行.其中一些(str = ...
)甚至不涉及任何指针.如果我的理解是正确的,那么strlen
就没有资格成为independent,因此unsequenced也就没有资格了.
这可能只是一个措辞问题,但它的目的是成为一架unsequenced?
关于可能的意图的说明
[[unsequenced]]
的建议声称,与GCC的[[gnu::const]]
不同,支持指针参数.然而,我不确定措辞是否反映了这一点,以及反映到了什么程度.