const char * foo()
{
return "abcdef";
}
int main()
{
printf("%s", foo());
}
符åˆæ ‡å‡†çš„编译器是å¦å¯ä»¥å†³å®šåœ¨å †æ ˆä¸Šåˆ†é…"abcdef"
?å³æ ‡å‡†ä¸çš„内容强制编译器在.data
部分ä¸åˆ†é…它?
ç”案 0 :(得分:25)
从C ++规范§2.14.5/ 8ä¸èŽ·å–å—符串文å—;
 Â普通å—符串文å—å’ŒUTF-8å—符串文å—也称为窄å—符串文å—。窄å—符串文å—的类型为“ n
const char
â€æ•°ç»„ï¼Œå…¶ä¸ n 是下é¢å®šä¹‰çš„å—符串大å°ï¼Œå¹¶ä¸”具有é™æ€å˜å‚¨æŒç»æ—¶é—´ï¼ˆ3.7)。
值得一æ的是,é™æ€å˜å‚¨æŒç»æ—¶é—´ï¼Œé€‚用于所有å—符串文å—;å› æ¤L""
,u""
,U""
ç‰; §2.14.5/ 10-12。
å过æ¥ï¼Œå¯¹äºŽé™æ€å˜å‚¨æŒç»æ—¶é—´Â§3.7.1/ 1;
 Â所有没有动æ€å˜å‚¨æŒç»æ—¶é—´ï¼Œæ²¡æœ‰çº¿ç¨‹å˜å‚¨æŒç»æ—¶é—´ä¸”ä¸æ˜¯æœ¬åœ°çš„å˜é‡éƒ½å…·æœ‰é™æ€å˜å‚¨æŒç»æ—¶é—´ã€‚这些实体的å˜å‚¨åº”在程åºæœŸé—´æŒç»ï¼ˆ3.6.2,3.6.3)。
å› æ¤ï¼Œæ‚¨çš„å—符串"abcdef"
将在程åºçš„æŒç»æ—¶é—´å†…å˜åœ¨ã€‚编译器å¯ä»¥é€‰æ‹©å˜å‚¨å®ƒçš„ä½ç½®ï¼ˆè¿™å¯èƒ½æ˜¯ç³»ç»Ÿçº¦æŸï¼‰ï¼Œä½†å®ƒå¿…é¡»ä¿æŒæœ‰æ•ˆã€‚
对于Cè¯è¨€è§„范(C11 draft n1570),å—符串文å—§6.4.5/ 6;
 Â在转æ¢é˜¶æ®µ7ä¸ï¼Œå°†å€¼ä¸ºé›¶çš„å—节或代ç é™„åŠ åˆ°ç”±å—符串文å—或文å—产生的æ¯ä¸ªå¤šå—节å—符åºåˆ—。然åŽä½¿ç”¨å¤šå—节å—符åºåˆ—åˆå§‹åŒ–é™æ€å˜å‚¨æŒç»æ—¶é—´æ•°ç»„,并且长度足以包å«åºåˆ—。对于å—符串文å—ï¼Œæ•°ç»„å…ƒç´ çš„ç±»åž‹ä¸º
char
,并使用多å—节å—符åºåˆ—çš„å„个å—节进行åˆå§‹åŒ–。
é™æ€å˜å‚¨æŒç»æ—¶é—´Â§6.2.4/ 3;
 Âå£°æ˜Žæ ‡è¯†ç¬¦çš„å¯¹è±¡æ²¡æœ‰å˜å‚¨ç±»è¯´æ˜Žç¬¦
_Thread_local
,并且具有外部或内部链接或å˜å‚¨ç±»è¯´æ˜Žç¬¦static,具有é™æ€å˜å‚¨æŒç»æ—¶é—´ã€‚ 它的生命周期是整个程åºçš„执行,它的å˜â€‹â€‹å‚¨å€¼åªåœ¨ç¨‹åºå¯åŠ¨ä¹‹å‰åˆå§‹åŒ–一次。
该ä½ç½®çš„相åŒç†ç”±é€‚用(很å¯èƒ½æ˜¯ç³»ç»Ÿçº¦æŸï¼‰ï¼Œä½†å¿…须在程åºæœŸé—´ä¿æŒæœ‰æ•ˆã€‚
ç”案 1 :(得分:6)
 Âæ ‡å‡†ä¸çš„内容强制编译器在.data上分é…它   部?
æ— ã€‚ä½†å®ƒè‚¯å®šä¸ä¼šåœ¨å †æ ˆä¸Šï¼Œå› 为指å‘å—符串文å—的指针永远ä¸ä¼šå¤±æ•ˆï¼ˆå› 为文å—具有é™æ€å˜å‚¨æŒç»æ—¶é—´ 1 ï¼‰ï¼Œå¹¶ä¸”å †æ ˆä¸Šçš„å€¼ä¼šè¢«æŸäº›å…¶ä»–帧覆盖点。具有é™æ€å˜å‚¨æŒç»æ—¶é—´çš„对象通常ä½äºŽä¸“用于æ¤çš„部分 - .data
部分。
在as-if规则下,如果程åºçš„å¯è§‚察行为没有改å˜ï¼Œä»–å¯ä»¥æŠŠå®ƒæ”¾åœ¨å †æ ˆä¸Š;但这ç§æƒ…况ä¸å¤ªå¯èƒ½å‘ç”Ÿï¼Œå› ä¸ºè¿™ä¸ä¼šä»¥ä»»ä½•æ–¹å¼ä½¿ç¨‹åºçš„性能å—ç›Šï¼ˆå¹¶ä¸”è¿˜æ²¡æœ‰ç¼–å†™æ— æ„义的相关编译器)。
1) [lex.string] / 8:
 Â也引用普通的å—符串文å—å’ŒUTF-8å—ç¬¦ä¸²æ–‡å— Â Â ä½œä¸ºçª„å—符串文å—。窄å—符串文å—的类型为“数组†  of n
const char
â€œï¼Œå…¶ä¸ n 是下é¢å®šä¹‰çš„å—符串的大å°ï¼Œ   并且具有é™æ€å˜å‚¨æŒç»æ—¶é—´ï¼ˆ3.7)。
ç”案 2 :(得分:6)
å‚考N1570(C11è‰æ¡ˆï¼‰6.4.5/6
å—符串文å—(强调我的未æ¥ï¼‰ï¼š
 Â在转æ¢é˜¶æ®µ7ä¸ï¼Œå°†å€¼ä¸ºé›¶çš„å—节或代ç é™„åŠ åˆ°æ¯ä¸ªå¤šå—节   由å—符串文å—或文å—产生的å—符åºåˆ—。 78)   然åŽä½¿ç”¨å¤šå—节å—符åºåˆ—åˆå§‹åŒ–数组   é™æ€å˜å‚¨æŒç»æ—¶é—´å’Œé•¿åº¦è¶³ä»¥åŒ…å« Â Â åºåˆ—。对于å—符串文å—ï¼Œæ•°ç»„å…ƒç´ å…·æœ‰ç±»åž‹  Â
char
,并使用多å—节的å•ä¸ªå—节进行åˆå§‹åŒ–   å—符åºåˆ—。
è¿™æ„味ç€å—符串文å—具有整个程åºæ‰§è¡Œçš„生命周期,如6.2.4/3
对象的å˜å‚¨æŒç»æ—¶é—´ä¸æ‰€è¿°ï¼š
 Â在没有å˜å‚¨ç±»çš„æƒ…å†µä¸‹å£°æ˜Žå…¶æ ‡è¯†ç¬¦çš„å¯¹è±¡   说明符
_Thread_local
,并且具有外部或内部链接或å˜å‚¨ç±»è¯´æ˜Žç¬¦static
,具有é™æ€å˜å‚¨æŒç»æ—¶é—´ã€‚它的   lifetime是程åºçš„整个执行åŠå…¶å˜å‚¨å€¼   仅在程åºå¯åŠ¨ä¹‹å‰åˆå§‹åŒ–。
编译器ä¸å¤ªå¯èƒ½å°†å®ƒä»¬æ”¾åœ¨å †æ ˆä¸Šï¼Œå› 为它的性质(æ示:在函数调用之间ä¿ç•™ï¼‰ã€‚
请注æ„,C Standard并未明确ç¦æ¢åœ¨å—符串上放置å—符串文å—ã€‚äº‹å®žä¸Šï¼Œå®ƒç”šè‡³æ²¡æœ‰å°†è¿™æ ·çš„æœ¯è¯å®šä¹‰ä¸ºå †æ ˆï¼Œä¹Ÿä¸å®šä¹‰.data
部分。这å–决于编译器,选择符åˆæ ‡å‡†çš„任何数æ®æ”¾ç½®ã€‚
ç”案 3 :(得分:3)
之å‰çš„ç”案已ç»ä»Žæ ‡å‡†ä¸å¼•ç”¨ï¼Œæ‰€ä»¥æˆ‘将采用逻辑方法。
您å¯ä»¥å°†æ¤æ–‡å—å—符串从ROæ•°æ®éƒ¨åˆ†å¤åˆ¶åˆ°æ¯æ¬¡è°ƒç”¨è¯¥å‡½æ•°çš„å †æ ˆä¸ï¼š
const char* foo()
{
const char str[] = "abcdef";
return str;
}
但是这个函数返回一个指针。
ä½ è‚¯å®šä¸å¸Œæœ›è¿™ä¸ªæŒ‡é’ˆåŒ…å«å †æ ˆä¸çš„地å€ã€‚
å› æ¤ï¼Œåœ¨å †æ ˆä¸Šåˆ†é…æ–‡å—å—符串是没有æ„义的。
ç”案 4 :(得分:3)
é™æ€æŒç»æ—¶é—´çš„所有内容必须ä¿æŒåˆ†é…,直到程åºé€€å‡º;这些东西å¯èƒ½ä½äºŽå †æ ˆä¸Šï¼Œä½†åªæœ‰åœ¨æ‰§è¡Œä»»ä½•ç”¨æˆ·ä»£ç 之å‰åˆ†é…å®ƒä»¬ã€‚è¿™æ ·çš„è®¾è®¡æ˜¯ä¸å¯»å¸¸çš„,但在例如å¯èƒ½æ˜¯æœ‰åˆ©çš„。一个æ’ä»¶æž¶æž„ï¼Œå¸Œæœ›æœ‰å‡ ä¸ªçº¿ç¨‹åŒæ—¶è¿è¡Œä¸€ä¸ªæ’件,让æ¯ä¸ªçº¿ç¨‹çš„实例完全独立è¿è¡Œã€‚如果架构将æ’件的所有实例共享相åŒçš„é™æ€æ•°æ®ï¼Œé‚£ä¹ˆè‡³å°‘从æ’件架构的角度æ¥çœ‹ï¼Œä¸åº”该共享的数æ®ä¸åº”该是é™æ€çš„。虽然让æ¯ä¸ªå®žä¾‹å°†å…¶é™æ€æ•°æ®å˜å‚¨åœ¨ä»Žå †è¯·æ±‚的空间å—ä¸å¯èƒ½æ›´å¥½ï¼Œä½†è¿™éœ€è¦è®©æ¯ä¸ªå®žä¾‹åœ¨å®Œæˆæ—¶é‡Šæ”¾è¯¥ç©ºé—´å—。让æ¯ä¸ªæ’ä»¶å®žä¾‹åœ¨å…¶å †æ ˆä¸Šåˆ†é…其所有数æ®ï¼ˆåŒ…括适当大å°çš„char[]
,在è¿è¡Œç”¨æˆ·ä»£ç 之å‰å°†å…¶ç»†åˆ†ä¸ºæ»¡è¶³malloc()
或new
请求)确ä¿æ€æ»ä¸Žå®žä¾‹å…³è”的线程会释放与之关è”çš„å˜å‚¨ã€‚