Note
ãã®ããŒãžã«ã¢ã¯ã»ã¹ããã«ã¯ãæ¿èªãå¿ èŠã§ãã ãµã€ã³ã€ã³ãŸãã¯ãã£ã¬ã¯ããªã®å€æŽã詊ãããšãã§ããŸãã
ãã®ããŒãžã«ã¢ã¯ã»ã¹ããã«ã¯ãæ¿èªãå¿ èŠã§ãã ãã£ã¬ã¯ããªã®å€æŽã詊ãããšãã§ããŸãã
24.1 å šè¬
å®å šã§ãªãã³ãŒãããµããŒãããªãå®è£ ã¯ããã®å¥ã§å®çŸ©ãããŠããæ§æèŠåã®äœ¿çšæ³ã蚺æããããã«å¿ èŠã§ãã
ãã®å¥ã®æ®ãã®éšå (ãã¹ãŠã®ãµãã¯ã©ãŠã¹ãå«ã) ã¯ãæ¡ä»¶ä»ãã§èŠç¯çã§ãã
泚: åã®å¥ã§å®çŸ©ãããŠããã³ã¢ C# èšèªã¯ããã€ã³ã¿ãŒãããŒã¿åãšããŠçç¥ããç¹ã§ C ããã³ C++ ãšã¯ç¹ã«ç°ãªããŸãã 代ããã«ãC# ã¯åç §ãšãã¬ããŒãž ã³ã¬ã¯ã¿ãŒã«ãã£ãŠç®¡çããããªããžã§ã¯ããäœæããæ©èœãæäŸããŸãã ãã®èšèšã¯ãä»ã®æ©èœãšçµã¿åãããŠãC# ã C ã C++ ãããã¯ããã«å®å šãªèšèªã«ããŸãã C# ã®ã³ã¢èšèªã§ã¯ãåæåãããŠããªã倿°ã"æªè§£æ±º" ãã€ã³ã¿ãŒããŸãã¯ãã®å¢çãè¶ ããŠé åã®ã€ã³ããã¯ã¹ãäœæããåŒãæã€ããšã¯ã§ããŸããã ãããã£ãŠãC ããã³ C++ ããã°ã©ã ãæ¥åžžçã«æ©ãŸããŠãããã°ã®ã«ããŽãªå šäœãæé€ãããŸãã
C ãŸã㯠C++ ã®ãã¹ãŠã®ãã€ã³ã¿ãŒåã³ã³ã¹ãã©ã¯ãã«ã¯ C# ã§å¯Ÿå¿ããåç §åããããŸãããããã§ããã€ã³ã¿ãŒåãžã®ã¢ã¯ã»ã¹ãå¿ èŠã«ãªãç¶æ³ããããŸãã ããšãã°ãåºã«ãªããªãã¬ãŒãã£ã³ã° ã·ã¹ãã ãšããåãããããã¡ã¢ãª ãããã ããã€ã¹ã«ã¢ã¯ã»ã¹ããããã¿ã€ã ã¯ãªãã£ã«ã«ãªã¢ã«ãŽãªãºã ãå®è£ ãããããããšã¯ããã€ã³ã¿ãŒã«ã¢ã¯ã»ã¹ããªããšäžå¯èœãŸãã¯å®çšçã§ãªãå ŽåããããŸãã ãã®ããŒãºã«å¯ŸåŠããããã«ãC# ã¯å®å šãªã³ãŒã èšè¿°ããæ©èœãæäŸã
å®å šã§ãªãã³ãŒãã§ã¯ããã€ã³ã¿ãŒã宣èšããŠæäœããããããŒã¿ ãã€ã³ã¿ãŒãšæŽæ°åã®éã®å€æãå®è¡ãããã倿°ãã¡ãœããã®ã¢ãã¬ã¹ãååŸãããããããšãã§ããŸãã ããæå³ã§ã¯ãå®å šã§ãªãã³ãŒããèšè¿°ããããšã¯ãC# ããã°ã©ã å ã§ C ã³ãŒããèšè¿°ããã®ãšãã䌌ãŠããŸãã
å®å šã§ãªãã³ãŒãã¯ãå®éã«ã¯éçºè ãšãŠãŒã¶ãŒã®äž¡æ¹ã®èгç¹ããèŠã "å®å šãª" æ©èœã§ãã å®å šã§ãªãã³ãŒãã¯ä¿®é£Ÿå
unsafeã§æç¢ºã«ããŒã¯ããå¿ èŠããããããéçºè ã¯å®å šã§ãªãæ©èœã誀ã£ãŠäœ¿çšããããšã¯ã§ãããå®è¡ãšã³ãžã³ã¯ä¿¡é ŒãããŠããªãç°å¢ã§å®å šã§ãªãã³ãŒããå®è¡ã§ããªãããã«åäœããŸããæ³šé
24.2 å®å šã§ãªãã³ã³ããã¹ã
C# ã®å®å
šã§ãªãæ©èœã¯ãå®å
šã§ãªãã³ã³ããã¹ãã§ã®ã¿äœ¿çšã§ããŸãã å®å
šã§ãªãã³ã³ããã¹ãã¯ãåãã¡ã³ããŒããŸãã¯ããŒã«ã«é¢æ°ã®å®£èšã« unsafe 修食åãå«ãããã unsafe_statementã䜿çšããŠå°å
¥ãããŸãã
- ã¯ã©ã¹ãæ§é äœãã€ã³ã¿ãŒãã§ã€ã¹ããŸãã¯ããªã²ãŒãã®å®£èšã«ã¯ã
unsafe修食åãå«ããããšãã§ããŸãããã®å Žåããã®å宣èšã®ããã¹ããšã¯ã¹ãã³ãå šäœ (ã¯ã©ã¹ãæ§é äœããŸãã¯ã€ã³ã¿ãŒãã§ã€ã¹ã®æ¬äœãå«ã) ã¯å®å šã§ãªãã³ã³ããã¹ããšèŠãªãããŸããæ³š: type_declaration ãéšåçãªå Žåããã®éšåã®ã¿ãå®å šã§ãªãã³ã³ããã¹ãã§ãã æ³šé
- ãã£ãŒã«ããã¡ãœãããããããã£ãã€ãã³ããã€ã³ãã¯ãµãŒãæŒç®åãã€ã³ã¹ã¿ã³ã¹ ã³ã³ã¹ãã©ã¯ã¿ãŒããã¡ã€ãã©ã€ã¶ãŒãéçã³ã³ã¹ãã©ã¯ã¿ãŒããŸãã¯ããŒã«ã«é¢æ°ã®å®£èšã«ã¯ã
unsafe修食åãå«ããããšãã§ããŸãããã®å Žåããã®ã¡ã³ããŒå®£èšã®ããã¹ããšã¯ã¹ãã³ãå šäœãå®å šã§ãªãã³ã³ããã¹ããšèŠãªãããŸãã - unsafe_statementã䜿çšãããšãblockå ã§å®å šã§ãªãã³ã³ããã¹ãã䜿çšã§ããŸãã é¢é£ä»ãããã block ã®ããã¹ããšã¯ã¹ãã³ãå šäœã¯ãå®å šã§ãªãã³ã³ããã¹ããšèŠãªãããŸãã å®å šã§ãªãã³ã³ããã¹ãå ã§å®£èšãããããŒã«ã«é¢æ°èªäœã¯å®å šã§ã¯ãããŸããã
é¢é£ããææ³æ¡åŒµã以äžã«ç€ºãããã®åŸã®ãµãã¯ã©ãŠã¹ã§ç€ºããŸãã
unsafe_modifier
: 'unsafe'
;
unsafe_statement
: 'unsafe' block
;
äŸ: 次ã®ã³ãŒãå
public unsafe struct Node { public int Value; public Node* Left; public Node* Right; }æ§é äœå®£èšã§æå®ããã
unsafe修食åã«ãããæ§é äœå®£èšã®ããã¹ããšã¯ã¹ãã³ãå šäœãå®å šã§ãªãã³ã³ããã¹ãã«ãªããŸãã ãããã£ãŠãLeftããã³Rightãã£ãŒã«ãããã€ã³ã¿ãŒåãšããŠå®£èšã§ããŸãã äžèšã®äŸãèšè¿°ã§ããŸãpublic struct Node { public int Value; public unsafe Node* Left; public unsafe Node* Right; }ããã§ã¯ããã£ãŒã«ã宣èšã®
unsafe修食åã«ãã£ãŠããããã®å®£èšãå®å šã§ãªãã³ã³ããã¹ããšèŠãªãããŸããend ã®äŸ
å®å
šã§ãªãã³ã³ããã¹ãã確ç«ããŠãã€ã³ã¿ãŒåã®äœ¿çšãèš±å¯ãã以å€ã«ã unsafe 修食åã¯åãŸãã¯ã¡ã³ããŒã«ã¯åœ±é¿ããŸããã
äŸ: 次ã®ã³ãŒãå
public class A { public unsafe virtual void F() { char* p; ... } } public class B : A { public override void F() { base.F(); ... } }
Fã®Aã¡ãœããã®å®å šã§ãªã修食åã¯ãFã®ããã¹ãç¯å²ããèšèªã®å®å šã§ãªãæ©èœã䜿çšã§ããå®å šã§ãªãã³ã³ããã¹ãã«ãªããŸããFã®Bã®ãªãŒããŒã©ã€ãã§ã¯ãunsafe修食åãåæå®ããå¿ èŠã¯ãããŸããããã¡ãããFã®Bã¡ãœããèªäœãå®å šã§ãªãæ©èœã«ã¢ã¯ã»ã¹ããå¿ èŠãããå Žåãé€ããŸãããã€ã³ã¿ãŒåãã¡ãœããã®ã·ã°ããã£ã®äžéšã§ããå Žåãç¶æ³ã¯è¥å¹²ç°ãªããŸã
public unsafe class A { public virtual void F(char* p) {...} } public class B: A { public unsafe override void F(char* p) {...} }ããã§ã¯ã
Fã®ã·ã°ããã£ã«ã¯ãã€ã³ã¿ãŒåãå«ãŸããŠãããããå®å šã§ãªãã³ã³ããã¹ãã§ã®ã¿èšè¿°ã§ããŸãã ãã ããå®å šã§ãªãã³ã³ããã¹ãã¯ãAã®å Žåãšåæ§ã«ã¯ã©ã¹å šäœãå®å šã«ããããunsafeã®å Žåãšåæ§ã«ãã¡ãœãã宣èšã«B修食åãå«ããããšã§å°å ¥ã§ããŸããend ã®äŸ
éšååå®£èš (unsafe) ã§ä¿®é£Ÿåã䜿çšãããŠããå Žåããã®ç¹å®ã®éšåã®ã¿ãå®å
šã§ãªãã³ã³ããã¹ããšèŠãªãããŸãã
24.3 ãã€ã³ã¿ãŒå
24.3.1 å šè¬
ãã€ã³ã¿ãŒã¯ããã® ãã€ã³ã¿ãŒ ã®ã¿ãŒã²ãããšåŒã°ãã倿°ãŸãã¯éçã¡ãœããã®ã¢ãã¬ã¹ãæ ŒçŽã§ãã倿°ã§ãã å€ null ãæã€ ãã€ã³ã¿ãŒã¯ null ãã€ã³ã¿ãŒã§ãããçŸåšã¯å€æ°ãŸãã¯éçã¡ãœãããæããŠããŸããã ãã€ã³ã¿ãŒã®ã¿ãŒã²ããã«ã¢ã¯ã»ã¹ããããšããè¡çºã¯ ãéåç
§ (§24.6.2 ãã㳠§24.6.4) ãšåŒã°ããŸãã
å®å šã§ãªãã³ã³ããã¹ãã§ã¯ã å (§8.1) ã pointer_typeã«ããããšãã§ããŸãã pointer_typeã¯ãé åã®èŠçŽ å (§17) ã§ãããŸããŸããã pointer_typeã¯ãå®å šã§ãªãã³ã³ããã¹ãã®å€éš (§12.8.18) ã®ååŒã§ã䜿çšã§ããŸã (ãã®ãããªäœ¿çšã¯å®å šã§ã¯ãããŸãã)ã
pointer_type
: dataptr_type
| funcptr_type
| voidptr_type
;
ãã€ã³ã¿ãŒåã®ã¿ãŒã²ããã®åã¯ããã€ã³ã¿ãŒåã® åç §å ã®å ãšåŒã°ããŸãã ããã¯ããã€ã³ã¿ãŒåã®å€ãæã倿°ã®åã衚ããŸãã
pointer_typeã¯ãå®å šã§ãªãã³ã³ããã¹ã (§24.2) ã®array_typeã§ã®ã¿äœ¿çšã§ããŸãã non_array_typeã¯ãããèªäœãarray_typeã§ã¯ãªãä»»æã®åã§ãã
åç § (åç §åã®å€) ãšã¯ç°ãªãããã€ã³ã¿ãŒã¯ã¬ããŒãž ã³ã¬ã¯ã¿ãŒã«ãã£ãŠè¿œè·¡ãããŸãããã¬ããŒãž ã³ã¬ã¯ã¿ãŒã¯ãã€ã³ã¿ãŒãšããã€ã³ã¿ãŒãæãããŒã¿ãŸãã¯éçã¡ãœãããèªèããŸããã ãã®ããããã€ã³ã¿ãŒã®åç §å ã®å㯠unmanaged_typeã«ãªããŸãã å®è£ ã§ã¯ãåç §å ã®åãšããŠãããŒãžãåãèš±å¯ã§ããŸãããã®å ŽåãèŠåãçæãããŸãã ãã€ã³ã¿ãŒåèªäœã¯ã¢ã³ãããŒãžåã§ããããããã€ã³ã¿ãŒåã¯å¥ã®ãã€ã³ã¿ãŒåã®åç §å åãšããŠäœ¿çšã§ããŸãã
ãã€ã³ã¿ãŒãšåç §ãæ··åšãããçŽæçãªã«ãŒã«ã¯ãåç § (ãªããžã§ã¯ã) ã®åç §å ã«ãã€ã³ã¿ãŒãå«ãããããããã€ã³ã¿ãŒã®åç §å ã«ã¯åç §ãå«ããªãããšãæå³ããŸãã
ç¹å®ã®å®è£ ã§ã¯ããã¹ãŠã®ãã€ã³ã¿ãŒåã®ãµã€ãºãšè¡šçŸãåãã§ããå¿ èŠããããŸãã null ãã€ã³ã¿ãŒå€ã¯ããã¹ãŠããã 0 ã§è¡šãããŸãã
ãã€ã³ã¿ãŒåã¯ãåã®å¥ã®ã«ããŽãªã§ãã åç
§åãšå€åãšã¯ç°ãªãããã€ã³ã¿ãŒå㯠object ããç¶æ¿ãããããã€ã³ã¿ãŒåãš objectã®éã«å€æã¯ååšããŸããã ç¹ã«ããã€ã³ã¿ãŒã®ããã¯ã¹åãšããã¯ã¹åè§£é€ (§8.3.13) ã¯ãµããŒããããŠããŸããã ãã ããç°ãªããã€ã³ã¿ãŒåéãããã³ãã€ã³ã¿ãŒåãšæŽæ°åã®éã§å€æãèš±å¯ãããŸãã ãã㯠§24.5 ã§èª¬æãããŠããŸãã
ååŒæ° (§8.4) ãšããŠpointer_typeã䜿çšããããšã¯ã§ããŸãããååŒæ°ããã€ã³ã¿ãŒåãšããŠæšè«ãããžã§ããªã㯠ã¡ãœããåŒã³åºãã§ã¯ãåæšè« (§12.6.3) ã¯å€±æããŸãã
åçã«ãã€ã³ããããæäœã®éšååŒã®åãšã㊠pointer_type ã䜿çšããããšã¯ã§ããŸãã (§12.3.3)ã
æ¡åŒµã¡ãœãã (§15.6.10) ã§ã¯ãpointer_typeãæåã®ãã©ã¡ãŒã¿ãŒã®åãšããŠäœ¿çšããããšã¯ã§ããŸããã
pointer_typeã¯ãæ®çºæ§ãã£ãŒã«ã (§15.5.4) ã®åãšããŠäœ¿çšã§ããŸãã
åã®E*ã¯ãEã®åçæ¶å»ã®åç
§å
åãæã€ãã€ã³ã¿ãŒåã§ãã
ãã€ã³ã¿ãŒåãæã€åŒã䜿çšããŠãanonymous_object_creation_expressionå ã®member_declaratorã®å€ãæå®ããããšã¯ã§ããŸãã (§12.8.17.3)ã
ãã€ã³ã¿ãŒåã®æ¢å®å€ (§9.3) ã nullã
ã¡ãœããã¯ãäœããã®åã®å€ãè¿ãããšãã§ããŸãããŸãããã®åã¯ãã€ã³ã¿ãŒã«ããããšãã§ããŸãã
äŸ:
intã®é£ç¶ããã·ãŒã±ã³ã¹ããã®ã·ãŒã±ã³ã¹ã®èŠçŽ æ°ãããã³ãã®ä»ã®intå€ãžã®ãã€ã³ã¿ãŒãæå®ãããšã次ã®ã¡ãœããã¯ãäžèŽããå Žåããã®ã·ãŒã±ã³ã¹å ã§ãã®å€ãæåã«åºçŸããã¢ãã¬ã¹ãè¿ããŸãããã以å€ã®å Žåã¯ãnullãè¿ããŸããunsafe static int* Find(int* pi, int size, int value) { for (int i = 0; i < size; ++i) { if (*pi == value) { return pi; } ++pi; } return null; }end ã®äŸ
24.3.2 ããŒã¿ ãã€ã³ã¿ãŒ
ããŒã¿ ãã€ã³ã¿ãŒã¯ãvalue_type (§8.3.1)ãfuncptr_type (§24.3.3)ããŸãã¯voidptr_type (§24.3.4) ãæã€å€æ°ã®ã¢ãã¬ã¹ãæ ŒçŽã§ãããã€ã³ã¿ãŒã§ãã
dataptr_type
: value_type ('*')+
| funcptr_type ('*')+
| voidptr_type ('*')+
;
dataptr_typeã¯ãunmanaged_type (§8.8)ãfuncptr_typeããŸãã¯voidptr_typeãšããŠæžã蟌ãŸãããã®åŸã« 1 ã€ä»¥äžã®* ããŒã¯ã³ãç¶ããŸãã
äŸ: ããŒã¿ ãã€ã³ã¿ãŒåã®äŸã次ã®è¡šã«ç€ºããŸãã
äŸ èª¬æ byte*ãžã®ãã€ã³ã¿ãŒ byteint*[]ãžã®ãã€ã³ã¿ãŒã® 1 次å é å intchar**ãã€ã³ã¿ãŒãžã®ãã€ã³ã¿ãŒ chardelegate*<void>*ãã©ã¡ãŒã¿ãŒããªããæ»ãå€ã®åã voidéçã¡ãœãããžã®ãã€ã³ã¿ãŒãžã®ãã€ã³ã¿ãŒvoid**äžæãªåãžã®ãã€ã³ã¿ãŒãžã®ãã€ã³ã¿ãŒ end ã®äŸ
泚: C ããã³ C++ ãšã¯ç°ãªããè€æ°ã®ãã€ã³ã¿ãŒãåã宣èšã§å®£èšãããŠããå ŽåãC# ã§ã¯ã
*ã¯åºã«ãªãåãšå ±ã«ã®ã¿æžã蟌ãŸããåãã€ã³ã¿ãŒåã®ãã¬ãã£ãã¯ã¹åºåãèšå·ãšããŠæžã蟌ãŸããŸããã æ¬¡ã«äŸã瀺ããŸããint* pi, pj; // NOT as int *pi, *pj;泚é
åã T* ããŒã¿ ãã€ã³ã¿ãŒã® null 以å€ã®å€ã¯ã Tåã®å€æ°ã®ã¢ãã¬ã¹ã衚ããŸãã ãã€ã³ã¿ãŒéæ¥æŒç®å * (§24.6.2) ã䜿çšããŠããã®å€æ°ã«ã¢ã¯ã»ã¹ã§ããŸãã
äŸ:
Påã®å€æ°int*ãæå®ãããšãåŒ*Pã¯ãintã«å«ãŸããã¢ãã¬ã¹ã«ããP倿°ã衚ããŸãã end ã®äŸ
泚: ãã€ã³ã¿ãŒã¯åç §æž¡ããã©ã¡ãŒã¿ãŒãšããŠæž¡ãããšãã§ããŸãããããŒã¿ ãã€ã³ã¿ãŒã䜿çšããŠæž¡ããšãæªå®çŸ©ã®åäœãçºçããå¯èœæ§ããããŸããããã¯ãåŒã³åºãããã¡ãœãããæ»ã£ããšãã«ååšããªããªã£ãããŒã«ã«å€æ°ãæãããã«ãã€ã³ã¿ãŒãèšå®ãããå Žåãããã€ã³ã¿ãŒãæããŠããåºå®ãªããžã§ã¯ããåºå®ãããªããªã£ãããã§ãã æ¬¡ã«äŸã瀺ããŸãã
using System; class Test { static int value = 20; unsafe static void F(out int* pi1, ref int* pi2) { int i = 10; pi1 = &i; fixed (int* pj = &value) { // ... pi2 = pj; } } static void Main() { int i = 10; unsafe { int* px1; int* px2 = &i; F(out px1, ref px2); // Undefined behavior // Console.WriteLine($"*px1 = {*px1}, *px2 = {*px2}"); } } }泚é
å®å šã§ãªãã³ã³ããã¹ãã§ã¯ãããŒã¿ ãã€ã³ã¿ãŒã§æäœããããã«ããã€ãã®ã³ã³ã¹ãã©ã¯ãã䜿çšã§ããŸãã
- åé
*æŒç®åã¯ããã€ã³ã¿ãŒéæ¥åç § (§24.6.2) ãå®è¡ããããã«äœ¿çšã§ããŸãã -
->æŒç®åã¯ããã€ã³ã¿ãŒ (§24.6.3) ãä»ããŠæ§é äœã®ã¡ã³ããŒã«ã¢ã¯ã»ã¹ããããã«äœ¿çšã§ããŸãã -
[]æŒç®åã䜿çšããŠãã€ã³ã¿ãŒã®ã€ã³ããã¯ã¹ãäœæã§ããŸã (§24.6.4)ã - åé
&æŒç®åã䜿çšããŠã倿°ã®ã¢ãã¬ã¹ãååŸã§ããŸã (§24.6.5)ã - ãã€ã³ã¿ãŒã®ã€ã³ã¯ãªã¡ã³ããšãã¯ãªã¡ã³ãã«ã¯ã
++æŒç®åãš--æŒç®åã䜿çšã§ããŸã (§24.6.6)ã - äºé
+æŒç®åãš-æŒç®åã䜿çšããŠãã€ã³ã¿ãŒæŒç®ãå®è¡ã§ããŸã (§24.6.7)ã - ãã€ã³ã¿ãŒã®æ¯èŒã«ã¯ã
==ã!=ã<ã>ã<=ãããã³>=æŒç®åã䜿çšã§ããŸã (§24.6.8)ã -
stackallocæŒç®åã䜿çšããŠãåŒã³åºãå±¥æŽ (§24.9) ããã¡ã¢ãªãå²ãåœãŠãããšãã§ããŸãã -
fixedã¹ããŒãã¡ã³ãã¯ãã¢ãã¬ã¹ãååŸã§ããããã«å€æ°ãäžæçã«ä¿®æ£ããããã«äœ¿çšã§ããŸã (§24.7)ã
24.3.3 颿°ãã€ã³ã¿ãŒ
颿°ãã€ã³ã¿ãŒã¯ãéçã¡ãœããã®ã¢ãã¬ã¹ãæ ŒçŽã§ãããã€ã³ã¿ãŒã§ãã
funcptr_type
: 'delegate' '*' calling_convention_specifier?
'<' funcptr_parameter_list funcptr_return_type '>'
;
calling_convention_specifier
: 'managed'
| 'unmanaged' ('[' unmanaged_calling_convention ']')?
;
unmanaged_calling_convention
: 'Cdecl'
| 'Stdcall'
| 'Thiscall'
| 'Fastcall'
| identifier (',' identifier)*
;
funcptr_parameter_list
: (funcptr_parameter ',')*
;
funcptr_parameter
: parameter_mode_modifier? type
;
funcptr_return_type
: ref_kind? return_type
;
ã¡ãœããã«ã·ã°ãã㣠(§7.5) ãããã®ãšåæ§ã«ã颿°ãã€ã³ã¿ãŒåã«ã¯ããããæãå¯èœæ§ãããã¡ãœããåã®ã·ã°ããã£ããããŸãã ãã®çœ²åã«ã¯ãåŒã³åºãèŠåãå«ãŸããŠããŸãã
å T ãæã€é¢æ°ãã€ã³ã¿ãŒã® null 以å€ã®å€ã¯ãå Tãšäºææ§ã®ããã·ã°ããã£ãæã€ã¡ãœããã®ã¢ãã¬ã¹ã衚ããŸãã
calling_convention_specifierãæå®ãããŠããªãå Žåãæ¢å®å€ã¯ managed ã§ãããå®è¡ç°å¢ã®æ¢å®ã®ã¡ã«ããºã ã䜿çšãããŸãã å®è£
å®çŸ©ã»ãã³ãã£ã¯ã¹ãæã€å®è£
å®çŸ©å ã« ããŒã¯ã³ãããããããunmanaged_calling_conventionã䜿çšããŠãç¹å®ã®ã¢ã³ãããŒãžèŠåãæå®ã§ããŸãã ãããã®ããŒã¯ã³ã®æå¹ãªçµã¿åããã®ã»ããã¯ãå®è£
ã§å®çŸ©ãããŠããŸãã
泚: calling_convention_specifier ã䜿çšãããšãããå¹ççãªåŒã³åºãã¡ã«ããºã ãéžæããããC# 以å€ã®èšèªã§èšè¿°ãããã¡ãœãããåŒã³åºãããããããšãã§ããŸãã æ³šéã
äŸ: 颿°ãã€ã³ã¿ãŒåã®äŸã次ã®è¡šã«ç€ºããŸãã
äŸ èª¬æ delegate*<void>ãã©ã¡ãŒã¿ãŒããªãã voidæ»ãå€ã®åãæããªããããŒãžã ã¡ãœãããžã®ãã€ã³ã¿ãŒdelegate*<void>[]ãã©ã¡ãŒã¿ãŒããªããæ»ãå€ã®åã voidãããŒãžã ã¡ãœãããžã®ãã€ã³ã¿ãŒã®é ådelegate*<string, string, bool>2 ã€ã® stringãã©ã¡ãŒã¿ãŒãšboolæ»ãå€ã®åãæã€ãããŒãžã ã¡ãœãããžã®ãã€ã³ã¿ãŒdelegate*<ref readonly int>ãã©ã¡ãŒã¿ãŒãæããããããè¿ããããŒãžã ã¡ãœãããžã®ãã€ã³ã¿ãŒ ref readonly intdelegate*<delegate*<int>, void>ãã©ã¡ãŒã¿ãŒããªããæ»ãå€ã®åã intã®ã¡ãœãããžã®ãã€ã³ã¿ãŒã§ãããæ»ãå€ã®åvoid1 ã€ã®ãã©ã¡ãŒã¿ãŒãæã€ãããŒãžã ã¡ãœãããžã®ãã€ã³ã¿ãŒdelegate* unmanaged[Stdcall]<void>voidåŒã³åºãèŠåã䜿çšããŠããã©ã¡ãŒã¿ãŒãšStdcallæ»ãå€ã®åãæããªãã¢ã³ãããŒãž ã¡ãœãããžã®ãã€ã³ã¿ãŒæ¬¡ã®ç¹ãèæ ®ããŠãã ããã
unsafe class Util { static void Log() { ... } static void Log(string p1) { ... } static void User() { delegate*<void>[] ary1 = new delegate*<void>[] { &Log, null }; foreach (var element in ary1) { if (element != null) { element(); // call the method being pointed to } } } }é åå ã®é¢æ°ãã€ã³ã¿ãŒããã©ã¡ãŒã¿ãŒã®ãªãã¡ãœãããæããŠããããšãèãããšã
&Logã¯ãã©ã¡ãŒã¿ãŒãæããªãLogã¡ãœããã®ã¢ãã¬ã¹ãåãåããŸãã end ã®äŸ
unmanaged_calling_conventionã§ã¯ãå°æ°ã®å®çŸ©æžã¿èŠå (CdeclãStdcallãThiscallãããã³FastcallããµããŒããããŠããŸãããããã¯ãã¹ãŠã³ã³ããã¹ã ããŒã¯ãŒãã§ã)ããããã¯ãã¹ã¿ã³ãã¢ãã³ãŸãã¯unmanaged_calling_conventionèå¥åãªã¹ãã®èå¥åãšããŠäœ¿çšã§ããŸãã ãã®ä»ã®å®è£
å®çŸ©èŠåãèš±å¯ãããŠããã èå¥åãªã¹ãã 䜿çšããŠè€æ°ã®èŠåãçµã¿åãããããšãã§ããŸããããã«ã¯ããããã®å®çŸ©æžã¿ã®èŠåã® 1 ã€ä»¥äžãå«ãŸããŠããå¯èœæ§ããããŸãã ãã®äžèЧã®èå¥åã®æ€çŽ¢ãšåŠçã¯ãå®è£
ã§å®çŸ©ãããæ¹æ³ã§è¡ãããŸãã
äŸ: å®è£ å®çŸ©ã®åŒã³åºãèŠå
SuppressGCTransitionãæå®ãããšãunsafe class C { delegate* unmanaged[SuppressGCTransition]<int, int> fpx; delegate* unmanaged[Stdcall, SuppressGCTransition]<int, int> fpy; }ã©ã¡ãã®å Žåããèå¥åãªã¹ãææ³èŠåã䜿çšãããŸãã end ã®äŸ
ã«ã¹ã¿ã 屿§ã¯ã funcptr_type ãŸãã¯ãã®èŠçŽ ã«ã¯é©çšã§ããŸããã
funcptr_typeåã®ãã©ã¡ãŒã¿ãŒã¯ãparams (§15.6.2.1) ãšããŠããŒã¯ããããšã¯ã§ããŸããã
å®å šã§ãªãã³ã³ããã¹ãã§ã¯ã颿°ãã€ã³ã¿ãŒã§æäœããããã«æ¬¡ã®ã³ã³ã¹ãã©ã¯ãã䜿çšã§ããŸãã
-
&æŒç®åã䜿çšããŠéçã¡ãœããã®ã¢ãã¬ã¹ãååŸã§ããŸã (§24.6.5) - ãã€ã³ã¿ãŒã®æ¯èŒã«ã¯ã
==ã!=ã<ã>ã<=ãããã³>=æŒç®åã䜿çšã§ããŸã (§24.6.8)ã - invocation_expressionæŒç®å (
()) ã䜿çšããŠãæããŠããã¡ãœãããåŒã³åºãããšãã§ããŸã (§12.8.9.1)ã
24.3.4 Void ãã€ã³ã¿ãŒ
void ãã€ã³ã¿ãŒã¯ãããŒã¿ ãã€ã³ã¿ãŒãŸãã¯é¢æ°ãã€ã³ã¿ãŒã®å€ãæ ŒçŽã§ãããã€ã³ã¿ãŒã§ãã
voidptr_type
: 'void' '*'
;
voidptr_typeã¯ããŒã¯ãŒã voidãšããŠæžã蟌ãŸãããã®åŸã«* ããŒã¯ã³ãç¶ããŸãã
äŸ: void ãã€ã³ã¿ãŒåã®äŸã次ã®è¡šã«ç€ºããŸãã
äŸ èª¬æ void*äžæãªåãžã®ãã€ã³ã¿ãŒ void*[,,]äžæãªåãžã®ãã€ã³ã¿ãŒã® 3 次å é å end ã®äŸ
voidptr_typeã¯ãäžæãªåãžã®ãã€ã³ã¿ãŒã衚ããŸãã åç
§å
ã®åã¯äžæã§ããããã鿥æŒç®åã void*åã®ãã€ã³ã¿ãŒã«é©çšããããšãããã®ãããªãã€ã³ã¿ãŒã«å¯ŸããŠç®è¡æŒç®ãå®è¡ããããšãã§ããŸããã ãã ãã void* åã®ãã€ã³ã¿ãŒã¯ãä»»æã®ãã€ã³ã¿ãŒå (ããã³ãã®é) ã«ãã£ã¹ãã§ããä»ã®ãã€ã³ã¿ãŒå (§24.6.8) ã®å€ãšæ¯èŒã§ããŸãã
24.4 åºå®å€æ°ãšç§»åå¯èœå€æ°
address-of æŒç®å (§24.6.5) ãš fixed ã¹ããŒãã¡ã³ã (§24.7) ã¯ã倿°ã åºå®å€æ°s ãš ç§»åå¯èœå€æ°s ãšãã 2 ã€ã®ã«ããŽãªã«åå²ããŸãã
åºå®å€æ°ã¯ãã¬ããŒãž ã³ã¬ã¯ã¿ãŒã®æäœã®åœ±é¿ãåããªãã¹ãã¬ãŒãžã®å Žæã«ååšããŸãã (åºå®å€æ°ã®äŸã«ã¯ãããŒã«ã«å€æ°ãå€ãã©ã¡ãŒã¿ãŒãããã³ããŒã¿ ãã€ã³ã¿ãŒã®éåç §ã«ãã£ãŠäœæããã倿°ãå«ãŸããŸã)ãäžæ¹ãç§»åå¯èœå€æ°ã¯ãã¬ããŒãž ã³ã¬ã¯ã¿ãŒã«ããåé 眮ãŸãã¯ç Žæ£ã®å¯Ÿè±¡ãšãªãã¹ãã¬ãŒãžã®å Žæã«ååšããŸãã (ç§»åå¯èœãªå€æ°ã®äŸã«ã¯ããªããžã§ã¯ãå ã®ãã£ãŒã«ããšé åã®èŠçŽ ãå«ãŸããŸã)ã
&æŒç®å (§24.6.5) ã§ã¯ãåºå®å€æ°ã®ã¢ãã¬ã¹ãå¶éãªãã§ååŸã§ããŸãã ãã ããç§»åå¯èœå€æ°ã¯ã¬ããŒãž ã³ã¬ã¯ã¿ãŒã«ãã£ãŠåé
眮ãŸãã¯ç Žæ£ãããå¯èœæ§ããããããç§»åå¯èœå€æ°ã®ã¢ãã¬ã¹ã¯ fixed statement (§24.7) ã䜿çšããŠã®ã¿ååŸã§ãããã®ã¢ãã¬ã¹ã¯ fixed ã¹ããŒãã¡ã³ãã®æéäžã®ã¿æå¹ãªãŸãŸã§ãã
æ£ç¢ºã«èšããšãåºå®å€æ°ã¯æ¬¡ã®ããããã§ãã
- 倿°ãé
staticå¿å颿° (§12.22.6.2) ã«ãã£ãŠãã£ããã£ãããªãéããããŒã«ã«å€æ°ãå€ãã©ã¡ãŒã¿ãŒããŸãã¯ãã©ã¡ãŒã¿ãŒ ã³ã¬ã¯ã·ã§ã³ãåç §ããsimple_name (§12.8.4) ã«èµ·å ãã倿°ã - ãã©ãŒã ã®member_access (
V.I) ã«èµ·å ãã倿°ãããã§ãVã¯struct_typeã®åºå®å€æ°ã§ãã - ãã©ãŒã ã®pointer_indirection_expression (
*P)ããã©ãŒã ã®pointer_member_access (P->I)ããŸãã¯ãã©ãŒã ã®pointer_element_access (P[E]) ã«èµ·å ãã倿°ã
ä»ã®ãã¹ãŠã®å€æ°ã¯ãç§»åå¯èœå€æ°ãšããŠåé¡ãããŸãã
éçãã£ãŒã«ãã¯ãç§»åå¯èœãªå€æ°ãšããŠåé¡ãããŸãã ãŸãããã©ã¡ãŒã¿ãŒã«æå®ãããåŒæ°ãåºå®å€æ°ã®å Žåã§ããåç §æž¡ããã©ã¡ãŒã¿ãŒã¯ç§»åå¯èœãªå€æ°ãšããŠåé¡ãããŸãã æåŸã«ãããŒã¿ ãã€ã³ã¿ãŒãéåç §ããããšã«ãã£ãŠçæããã倿°ã¯ãåžžã«åºå®å€æ°ãšããŠåé¡ãããŸãã
24.5 ãã€ã³ã¿ãŒå€æ
24.5.1 å šè¬
å®å šã§ãªãã³ã³ããã¹ãã§ã¯ã䜿çšå¯èœãªæé»çãªå€æã®ã»ãã (§10.2) ãæ¡åŒµãããæ¬¡ã®æé»çãªãã€ã³ã¿ãŒå€æãå«ãŸããŸãã
- ä»»æã® pointer_type ããå
void*ã - null_literal (§6.4.5.7) ããä»»æã®pointer_typeã
-
funcptr_type
Uããfuncptr_typeVãŸã§ã次ã®ãã¹ãŠãåœãŠã¯ãŸãå Žåã-
UãšVã¯åãæ°ã®ãã©ã¡ãŒã¿ãŒãæã¡ãUáµ¢ã®åãã©ã¡ãŒã¿ãŒUã¯ãVáµ¢ã®å¯Ÿå¿ãããã©ã¡ãŒã¿ãŒVãšåãåç §æž¡ããã©ã¡ãŒã¿ãŒä¿®é£Ÿåãæã¡ãŸãã - å€ãã©ã¡ãŒã¿ãŒããšã«ãid 倿ãæé»çãªåç
§å€æããŸãã¯æé»çãªãã€ã³ã¿ãŒå€æã¯ã
Uã®ãã©ã¡ãŒã¿ãŒåããVã®å¯Ÿå¿ãããã©ã¡ãŒã¿ãŒåã«ååšããŸãã - åç
§æž¡ããã©ã¡ãŒã¿ãŒããšã«ã
Uã®ãã©ã¡ãŒã¿ãŒåã¯ãVã®å¯Ÿå¿ãããã©ã¡ãŒã¿ãŒåãšåãã§ãã - æ»ãå€ã®åãå€ã®å Žåã
Uã®æ»ãå€ã®åããVã®æ»ãå€ã®åãžã® IDãæé»çãªåç §ããŸãã¯æé»çãªãã€ã³ã¿ãŒå€æãååšããŸãã - æ»ãå€ã®åãåç
§åã®å Žåã
refã®æ»ãå€ã®åããã³V修食åã¯ãrefã®æ»ãå€ã®åããã³U修食åãšåãã§ãã -
Uã®åŒã³åºãèŠåã¯ãVã®åŒã³åºãèŠåãšåãã§ãã
-
ããã«ãå®å šã§ãªãã³ã³ããã¹ãã§ã¯ã䜿çšå¯èœãªæç€ºçãªå€æã®ã»ãã (§10.3) ãæ¡åŒµãããæ¬¡ã®æç€ºçãªãã€ã³ã¿ãŒå€æãå«ãŸããŸãã
- ä»»æã® pointer_type ããä»ã® pointer_typeãŸã§ã
-
sbyteãbyteãshortãushortãintãuintãnintãnuintãlongãulongããä»»æã®pointer_typeãŸã§ã -
ä»»æã®pointer_typeããã
sbyteãbyteãshortãushortãintãuintãnintãnuintãlongããŸãã¯ulongãŸã§ã
æåŸã«ãå®å šã§ãªãã³ã³ããã¹ãã§ã¯ãæšæºã®æé»çãªå€æã®ã»ãã (§10.4.2) ã«ã¯ã次ã®ãã€ã³ã¿ãŒå€æãå«ãŸããŸãã
- ä»»æã® pointer_type ããå
void*ã - null_literalããä»»æã®pointer_typeãžã
2 ã€ã®ãã€ã³ã¿ãŒåéã®å€æã§ã¯ãå®éã®ãã€ã³ã¿ãŒå€ã¯å€æŽãããŸããã ã€ãŸãããããã€ã³ã¿ãŒåããå¥ã®ãã€ã³ã¿ãŒåãžã®å€æã¯ããã€ã³ã¿ãŒã«ãã£ãŠæå®ãããåºã«ãªãã¢ãã¬ã¹ã«ã¯åœ±é¿ããŸããã
1 ã€ã®ãã€ã³ã¿ãŒåã dataptr_typeã«å€æããããšãã«ãçµæã®ãã€ã³ã¿ãŒããã€ã³ãå
ã®åã«å¯ŸããŠæ£ããé
眮ãããŠããªãå Žåãçµæãéåç
§ãããå Žåãåäœã¯æªå®çŸ©ã«ãªããŸãã äžè¬ã«ã"æ£ããé
眮" ãšããæŠå¿µã¯æšç§»çã§ããå A ãžã®ãã€ã³ã¿ãŒãå Bãžã®ãã€ã³ã¿ãŒã«å¯ŸããŠæ£ããé
眮ããããã®ãã€ã³ã¿ãŒãå Cãžã®ãã€ã³ã¿ãŒã«å¯ŸããŠæ£ããé
眮ãããŠããå Žåã A åãžã®ãã€ã³ã¿ãŒã¯å Cãžã®ãã€ã³ã¿ãŒã«å¯ŸããŠæ£ããé
眮ãããŸãã
äŸ: 1 ã€ã®åãæã€å€æ°ã«å¥ã®åãžã®ãã€ã³ã¿ãŒãä»ããŠã¢ã¯ã»ã¹ããå ŽåãèããŠã¿ãŸãã
unsafe static void M() { char c = 'A'; char* pc = &c; void* pv = pc; int* pi = (int*)pv; // pretend a 16-bit char is a 32-bit int int i = *pi; // read 32-bit int; undefined *pi = 123456; // write 32-bit int; undefined }end ã®äŸ
ãã€ã³ã¿ãŒåã byteãžã®ãã€ã³ã¿ãŒã«å€æããããšãçµæã¯å€æ°ã®æäžäœã®ã¢ãã¬ã¹æå®ããã byte ãæããŸãã 倿°ã®ãµã€ãºãŸã§ãçµæã®é£ç¶ããã€ã³ã¯ãªã¡ã³ãã«ããããã®å€æ°ã®æ®ãã®ãã€ããžã®ãã€ã³ã¿ãŒãçæãããŸãã
äŸ: 次ã®ã¡ãœããã¯ã
doubleå ã® 8 ãã€ãããããã 16 鲿°ã®å€ãšããŠè¡šç€ºããŸããclass Test { static void Main() { double d = 123.456e23; unsafe { byte* pb = (byte*)&d; for (int i = 0; i < sizeof(double); ++i) { Console.Write($" {*pb++:X2}"); } Console.WriteLine(); } } }ãã¡ãããçæãããåºåã¯ãšã³ãã£ã¢ã³ã«ãã£ãŠç°ãªããŸãã 1 ã€ã®å¯èœæ§ã¯
" BA FF 51 A2 90 6C 24 45"ãend ã®äŸ
ãã€ã³ã¿ãŒãšæŽæ°ã®éã®ãããã³ã°ã¯ãå®è£ ã§å®çŸ©ãããŸãã
泚: ãã ããç·åœ¢ã¢ãã¬ã¹ç©ºéãæã€ 32 ãããããã³ 64 ãããã® CPU ã¢ãŒããã¯ãã£ã§ã¯ãæŽæ°åãšã®éã§ã®ãã€ã³ã¿ãŒã®å€æã¯ãéåžžã
uintå€ãŸãã¯ulongå€ã®å€æãšãŸã£ããåãããã«åäœããŸãã æ³šé
24.5.2 ãã€ã³ã¿ãŒé å
ãã€ã³ã¿ãŒã®é åã¯ãå®å šã§ãªãã³ã³ããã¹ã ã§array_creation_expression (§12.8.17.4) ã䜿çšããŠæ§ç¯ã§ããŸãã ãã€ã³ã¿ãŒé åã§ã¯ãä»ã®é ååã«é©çšãããäžéšã®å€æã®ã¿ãèš±å¯ãããŸãã
- ä»»æã®array_typeãããžã®æé»çãªåç
§å€æ (
System.Array) ãšããããå®è£ ããã€ã³ã¿ãŒãã§ã€ã¹ããã€ã³ã¿ãŒé åã«é©çšãããŸãã ãã ãããã€ã³ã¿ãŒåã¯System.Arrayã«å€æãããªããããobjectãŸãã¯å®è£ ããã€ã³ã¿ãŒãã§ã€ã¹ãä»ããŠé åèŠçŽ ã«ã¢ã¯ã»ã¹ããããšãããšãå®è¡æã«äŸå€ãçºçããå¯èœæ§ããããŸãã - 1 次å
é
å åãã ãžã®æé»çããã³æç€ºçãªåç
§å€æ (
S[]ãSystem.Collections.Generic.IList<T>) ã¯ãã€ã³ã¿ãŒé åã«ã¯é©çšãããŸããã -
ããã®æç€ºçãªåç
§å€æ (
System.Array) ãšãarray_typeã«å®è£ ãããã€ã³ã¿ãŒãã§ã€ã¹ã¯ãã€ã³ã¿ãŒé åã«é©çšãããŸãã - ãã€ã³ã¿ãŒåã¯ååŒæ°ãšããŠäœ¿çšã§ããããã€ã³ã¿ãŒåããéãã€ã³ã¿ãŒåãžã®å€æããªãããããšãã®åºæ¬ã€ã³ã¿ãŒãã§ã€ã¹ããåäžæ¬¡å
é
ååãžã®æç€ºçãªåç
§å€æ (
System.Collections.Generic.IList<S>T[]) ã¯ãã€ã³ã¿ãŒé åã«ã¯é©çšãããŸããã
ãããã®å¶éã¯ã§9.4.4.17 ã§èª¬æãããŠããé
åã«å¯Ÿããforeach ã¹ããŒãã¡ã³ãã®æ¡åŒµãã€ã³ã¿ãŒé
åã«é©çšã§ããªãããšãæå³ããŸãã 代ããã«ããã©ãŒã ã® foreach ã¹ããŒãã¡ã³ã
foreach (V v in x)
embedded_statement
ããã§ã x ã®åã¯ãã©ãŒã T[,,...,]ã®é
ååã§ãã n ã¯æ¬¡å
ã®æ°ãã 1 ãåŒããå€ã§ã T ãŸã㯠V ã¯ãã€ã³ã¿ãŒåã§ãããæ¬¡ã®ããã«å
¥ãåã«ãªã£ã for ã«ãŒãã䜿çšããŠå±éãããŸãã
{
T[,,...,] a = x;
for (int i0 = a.GetLowerBound(0); i0 <= a.GetUpperBound(0); i0++)
{
for (int i1 = a.GetLowerBound(1); i1 <= a.GetUpperBound(1); i1++)
{
...
for (int in = a.GetLowerBound(n); in <= a.GetUpperBound(n); in++)
{
V v = (V)a[i0,i1,...,in];
*embedded_statement*
}
}
}
}
倿° aã i0ã i1ã...
in ã¯ã x ã embedded_statement ããŸãã¯ããã°ã©ã ã®ãã®ä»ã®ãœãŒã¹ ã³ãŒãã«å¯ŸããŠè¡šç€ºãŸãã¯ã¢ã¯ã»ã¹ã§ããŸããã
v倿°ã¯ãåã蟌ã¿ã¹ããŒãã¡ã³ãã§ã¯èªã¿åãå°çšã§ãã
(èŠçŽ å) ããTãžã®æç€ºçãªå€æ (V) ããªãå Žåã¯ããšã©ãŒãçæããããã以äžã®æé ã¯å®è¡ãããŸããã
xå€ãnullå Žåãå®è¡æã«System.NullReferenceExceptionãã¹ããŒãããŸãã
泚: ãã€ã³ã¿ãŒåã¯ååŒæ°ãšããŠäœ¿çšã§ããŸãããããã€ã³ã¿ãŒé åã¯ååŒæ°ãšããŠäœ¿çšã§ããŸãã æ³šé
24.6 åŒå ã®ãã€ã³ã¿ãŒ
24.6.1 å šè¬
ã¢ã³ã»ãŒã ã³ã³ããã¹ãã§ã¯ãåŒã¯ãã€ã³ã¿ãŒåã®çµæãçæããå¯èœæ§ããããŸãããå®å šã§ãªãã³ã³ããã¹ãã®å€éšã§ã¯ãåŒããã€ã³ã¿ãŒåã®ã³ã³ãã€ã«æãšã©ãŒã«ãªããŸãã æ£ç¢ºã«ã¯ãå®å šã§ãªãã³ã³ããã¹ãã®å€éšã§ã¯ã simple_name (§12.8.4) member_access (§12.8.7)ã invocation_expression (§12.8.10)ããŸã㯠element_access (§12.8.12) ããã€ã³ã¿ãŒåã§ãã
å®å šã§ãªãã³ã³ããã¹ãã§ã¯ã primary_expression (§12.8) ãš unary_expression (§12.9) ã®éçšç°å¢ã§è¿œå ã®ã³ã³ã¹ãã©ã¯ããèš±å¯ãããŸããããã¯ã次ã®ãµãã¯ã©ãŠã¹ã§èª¬æãããŠããŸãã
泚: å®å šã§ãªãæŒç®åã®åªå é äœãšçµåèŠåã¯ãææ³ã«ãã£ãŠæé»çã«ç€ºãããŸãã æ³šé
颿°ãã€ã³ã¿ãŒã«é¢ããåæšè«ã®ãã¹ãŠã®åŽé¢ã¯ã§12.6 ãã㳠§12.8 ã®å¯Ÿå¿ãããµãã¯ã©ãŠã¹ã§èª¬æãããŠããŸãã
24.6.2 ãã€ã³ã¿ãŒã®éæ¥åç §
pointer_indirection_expressionã¯ãã¢ã¹ã¿ãªã¹ã¯ (*) ãšããã«ç¶ãunary_expressionã§æ§æãããŸãã
pointer_indirection_expression
: '*' unary_expression
;
åé
* æŒç®åã¯ãã€ã³ã¿ãŒéæ¥åç
§ã瀺ããããŒã¿ ãã€ã³ã¿ãŒãæã倿°ãååŸããããã«äœ¿çšãããŸãã
*Pãè©äŸ¡ããçµæ (Pã¯T*ããŒã¿ ãã€ã³ã¿ãŒåã®åŒ) ã¯ãTåã®å€æ°ã§ãã åé
* æŒç®åãå funcptr_typeãŸãã¯voidptr_type ãæã€ ãªãã©ã³ãããŸã㯠ãã€ã³ã¿ãŒåã§ã¯ãªãåŒã«é©çšããã®ã¯ã³ã³ãã€ã«æãšã©ãŒã§ãã
泚: C/C++ ã§ã¯ã
(*fp)()ã®ããã«ã颿°ãã€ã³ã¿ãŒãéåç §ããŠåºã«ãªã颿°ã§ååŸããŠåŒã³åºãããšãã§ããŸãã ãã®ãããªæç€ºçãªéåç §ã¯ C# ã§ã¯èš±å¯ãããŠããŸããã æ³šé
åé
* æŒç®åã null ããŒã¿ ãã€ã³ã¿ãŒã«é©çšããå Žåã®å¹æã¯ãå®è£
ã§å®çŸ©ãããŸãã ç¹ã«ããã®æäœã§ System.NullReferenceExceptionãã¹ããŒãããä¿èšŒã¯ãããŸããã
ç¡å¹ãªå€ãããŒã¿ ãã€ã³ã¿ãŒã«å²ãåœãŠãããŠããå Žåãåé
* æŒç®åã®åäœã¯æªå®çŸ©ã§ãã
泚: åé
*æŒç®åã«ãã£ãŠããŒã¿ ãã€ã³ã¿ãŒãéåç §ããããã®ç¡å¹ãªå€ã®äžã«ã¯ãæãåã«å¯ŸããŠäžé©åã«ã¢ã©ã€ã³ãããã¢ãã¬ã¹ ( §24.5 ã®äŸãåç §) ãšãæå¹æéãçµäºããåŸã®å€æ°ã®ã¢ãã¬ã¹ããããŸãã
æç¢ºãªä»£å
¥åæã®ããã«ããã©ãŒã *P ã®åŒãè©äŸ¡ããããšã«ãã£ãŠçæããã倿°ã¯ãæåã«ä»£å
¥ããããã®ãšèŠãªãããŸã (§9.4.2)ã
24.6.3 ãã€ã³ã¿ãŒ ã¡ã³ã㌠ã¢ã¯ã»ã¹
pointer_member_accessã¯ãprimary_expressionããã®åŸã« "->" ããŒã¯ã³ããã®åŸã« identifier ããã³çç¥å¯èœãªtype_argument_listã§æ§æãããŸãã
pointer_member_access
: primary_expression '->' identifier type_argument_list?
;
ãã©ãŒã P->Iã®ãã€ã³ã¿ãŒ ã¡ã³ã㌠ã¢ã¯ã»ã¹ã§ã¯ã P ã¯ããŒã¿ ãã€ã³ã¿ãŒåã®åŒã§ã I ã¯ã P ããã€ã³ãããåã®ã¢ã¯ã»ã¹å¯èœãªã¡ã³ããŒã衚ãå¿
èŠããããŸãã
P
funcptr_typeãŸãã¯voidptr_typeã®ã³ã³ãã€ã«æãšã©ãŒã§ãã
ãã©ãŒã P->I ã®ãã€ã³ã¿ãŒ ã¡ã³ã㌠ã¢ã¯ã»ã¹ã¯ã (*P).IãšãŸã£ããåãããã«è©äŸ¡ãããŸãã ãã€ã³ã¿ãŒéæ¥æŒç®å (*) ã®èª¬æã«ã€ããŠã¯ã §24.6.2 ãåç
§ããŠãã ããã ã¡ã³ã㌠ã¢ã¯ã»ã¹æŒç®å (.) ã®èª¬æã«ã€ããŠã¯ã §12.8.7 ãåç
§ããŠãã ããã
äŸ: 次ã®ã³ãŒãå
struct Point { public int x; public int y; public override string ToString() => $"({x},{y})"; } class Test { static void Main() { Point point; unsafe { Point* p = &point; p->x = 10; p->y = 20; Console.WriteLine(p->ToString()); } } }
->æŒç®åã¯ããã£ãŒã«ãã«ã¢ã¯ã»ã¹ãããã€ã³ã¿ãŒãä»ããŠæ§é äœã®ã¡ãœãããåŒã³åºãããã«äœ¿çšãããŸãã æäœP->Iã¯(*P).Iãšæ£ç¢ºã«çããã®ã§ãMainã¡ãœãããåæ§ã«èšè¿°ãããŠããå¯èœæ§ããããŸããclass Test { static void Main() { Point point; unsafe { Point* p = &point; (*p).x = 10; (*p).y = 20; Console.WriteLine((*p).ToString()); } } }end ã®äŸ
24.6.4 ãã€ã³ã¿ãŒèŠçŽ ã®ã¢ã¯ã»ã¹
pointer_element_accessã¯ãprimary_expressionã®åŸã« ã"[" ãš "]" ã§å²ãŸããåŒã§æ§æãããŸãã
pointer_element_access
: primary_expression '[' expression ']'
;
element_accessãšpointer_element_access (§24.6.4) ã®äž¡æ¹ã®ä»£æ¿ææ®µãé©çšãããå Žåãprimary_expressionãèªèããå Žåã¯ãåã蟌ã¿primary_expressionããã€ã³ã¿ãŒå (§24.3) ã®å Žåã¯ãåŸè ãéžæããå¿ èŠããããŸãã
ãã©ãŒã P[E]ã®ãã€ã³ã¿ãŒèŠçŽ ã¢ã¯ã»ã¹ã§ã¯ã P 㯠void*以å€ã®ãã€ã³ã¿ãŒåã®åŒã§ã E ã¯æé»çã« intã uintã nintã nuintã longããŸã㯠ulongã«å€æã§ããåŒã§ããå¿
èŠããããŸãã
ãã©ãŒã P[E] ã®ãã€ã³ã¿ãŒèŠçŽ ã®ã¢ã¯ã»ã¹ã¯ã *(P + E)ãšãŸã£ããåãããã«è©äŸ¡ãããŸãã ãã€ã³ã¿ãŒéæ¥æŒç®å (*) ã®èª¬æã«ã€ããŠã¯ã §24.6.2 ãåç
§ããŠãã ããã ãã€ã³ã¿ãŒå ç®æŒç®å (+) ã®èª¬æã«ã€ããŠã¯ã §24.6.7 ãåç
§ããŠãã ããã
äŸ: 次ã®ã³ãŒãå
class Test { static void Main() { unsafe { char* p = stackalloc char[256]; for (int i = 0; i < 256; i++) { p[i] = (char)i; } } } }ãã€ã³ã¿ãŒèŠçŽ ã®ã¢ã¯ã»ã¹ã¯ã
forã«ãŒãå ã®æåãããã¡ãŒãåæåããããã«äœ¿çšãããŸãã æäœP[E]ã¯*(P + E)ãšæ£ç¢ºã«çããã®ã§ãäŸãåæ§ã«èšè¿°ãããŠããå¯èœæ§ããããŸããclass Test { static void Main() { unsafe { char* p = stackalloc char[256]; for (int i = 0; i < 256; i++) { *(p + i) = (char)i; } } } }end ã®äŸ
ãã€ã³ã¿ãŒèŠçŽ ã®ã¢ã¯ã»ã¹æŒç®åã¯ãç¯å²å€ã®ãšã©ãŒããã§ãã¯ããŸããããŸããå¢çå€ã®èŠçŽ ã«ã¢ã¯ã»ã¹ãããšãã®åäœã¯æªå®çŸ©ã§ãã
泚: ãã㯠C ããã³ C++ ãšåãã§ãã æ³šé
24.6.5 address-of æŒç®å
addressof_expressionã¯ã¢ã³ããµã³ã (&) ãšããã«ç¶ãunary_expressionã§æ§æãããŸãã
addressof_expression
: '&' unary_expression
;
unary_expression 倿°ãŸãã¯ã¡ãœãã ã°ã«ãŒããæå®ããå¿ èŠããããŸãã 倿°ã®ã±ãŒã¹ã¯ãçŽäžã§èª¬æããŸãã
åŒETåã§ãåºå®å€æ° (§24.4) ãšããŠåé¡ãããŠããå Žåãã³ã³ã¹ãã©ã¯ã&EEã«ãã£ãŠæå®ããã倿°ã®ã¢ãã¬ã¹ãèšç®ãããŸãã çµæã®å㯠T* ãããå€ãšããŠåé¡ãããŸãã
TããããŒãžãåã®å Žåã¯ãèŠåãçæãããŸãã ã³ã³ãã€ã«æãšã©ãŒã¯ã E ã倿°ãšããŠåé¡ãããŠããªãå Žåã E ãèªã¿åãå°çšã®ããŒã«ã«å€æ°ãšããŠåé¡ãããŠããå ŽåããŸãã¯ç§»åå¯èœãªå€æ° E 瀺ããŠããå Žåã«çºçããŸãã æåŸã®ã±ãŒã¹ã§ã¯ãåºå®ã¹ããŒãã¡ã³ã (§24.7) ã䜿çšããŠãã¢ãã¬ã¹ãååŸããåã«å€æ°ãäžæçã« "ä¿®æ£" ã§ããŸãã
泚: §12.8.7 ã«èšèŒãããŠããããã«
readonlyãã£ãŒã«ããå®çŸ©ããæ§é äœãŸãã¯ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ ã³ã³ã¹ãã©ã¯ã¿ãŒãŸãã¯éçã³ã³ã¹ãã©ã¯ã¿ãŒã®å€åŽã§ã¯ããã®ãã£ãŒã«ãã¯å€æ°ã§ã¯ãªãå€ãšèŠãªãããŸãã ãã®ããããã®ã¢ãã¬ã¹ã¯ååŸã§ããŸããã åæ§ã«ã宿°ã®ã¢ãã¬ã¹ã¯ååŸã§ããŸããã æ³šé
&æŒç®åã§ã¯ããªãã©ã³ãã確å®ã«å²ãåœãŠãå¿
èŠã¯ãããŸãããã&æŒç®ã®åŸãæäœãé©çšããã倿°ã¯ãæäœãå®è¡ãããå®è¡ãã¹ã§ç¢ºå®ã«å²ãåœãŠãããŠãããšèŠãªãããŸãã ãã®ç¶æ³ã§å€æ°ã®æ£ããåæåãå®éã«è¡ãããããšãä¿èšŒããã®ã¯ããã°ã©ãã®è²¬ä»»ã§ãã
äŸ: 次ã®ã³ãŒãå
class Test { static void Main() { int i; unsafe { int* p = &i; *p = 123; } Console.WriteLine(i); } }
iã¯ã&iã®åæåã«äœ¿çšãããpæäœã«åŸã£ãŠç¢ºå®ã«å²ãåœãŠãããŠãããšèŠãªãããŸãã*pãžã®å²ãåœãŠã¯å®éã«ã¯iåæåãããŸããããã®åæåãå«ããããšã¯ããã°ã©ãã®è²¬ä»»ã§ãããå²ãåœãŠãåé€ãããå Žåãã³ã³ãã€ã«æãšã©ãŒã¯çºçããŸãããend ã®äŸ
泚: ããŒã«ã«å€æ°ã®åé·ãªåæåãåé¿ã§ããããã«ã
&æŒç®åã®æç¢ºãªå²ãåœãŠã®èŠåãååšããŸãã ããšãã°ãå€ãã®å€éš API ã¯ãAPI ã«ãã£ãŠå ¥åãããæ§é äœãžã®ãã€ã³ã¿ãŒãåãåããŸãã ãã®ãã㪠API ã®åŒã³åºãã¯ãéåžžãããŒã«ã«æ§é äœå€æ°ã®ã¢ãã¬ã¹ãæž¡ããŸããèŠåããªãå Žåã¯ãæ§é äœå€æ°ã®åé·ãªåæåãå¿ èŠã«ãªããŸãã æ³šé
泚: ããŒã«ã«å€æ°ãå€ãã©ã¡ãŒã¿ãŒããŸãã¯ãã©ã¡ãŒã¿ãŒ ã³ã¬ã¯ã·ã§ã³ãå¿å颿° (§12.8.24) ã«ãã£ãŠãã£ããã£ãããå Žåããã®ããŒã«ã«å€æ°ããã©ã¡ãŒã¿ãŒããŸãã¯ãã©ã¡ãŒã¿ãŒ ã³ã¬ã¯ã·ã§ã³ã¯åºå®å€æ° (§24.7) ãšèŠãªãããªããªããŸãããã代ããã«ç§»åå¯èœãªå€æ°ãšèŠãªãããŸãã ãããã£ãŠãå¿å颿°ã«ãã£ãŠãã£ããã£ãããããŒã«ã«å€æ°ãå€ãã©ã¡ãŒã¿ãŒããŸãã¯ãã©ã¡ãŒã¿ãŒ ã³ã¬ã¯ã·ã§ã³ã®ã¢ãã¬ã¹ãååŸããã®ã¯ãå®å šã§ãªãã³ãŒãã®ãšã©ãŒã§ãã æ³šé
æ¹æ³çŸ€ãæå® unary_expression å Žåã¯çŽäžã«èª¬æããã
å®å
šã§ãªãã³ã³ããã¹ãã§ã¯ãMã¡ãœããã¯ã次ã®ãã¹ãŠã«è©²åœããå ŽåFãšäºææ§ããããŸãã
-
MFã¯åãæ°ã®ãã©ã¡ãŒã¿ãŒãæã¡ãMã®åãã©ã¡ãŒã¿ãŒã«ã¯ãrefã®å¯Ÿå¿ãããã©ã¡ãŒã¿ãŒãšåãoutãinããŸãã¯F修食åããããŸãã - å€ãã©ã¡ãŒã¿ãŒããšã«ãid 倿ãæé»çãªåç
§å€æããŸãã¯æé»çãªãã€ã³ã¿ãŒå€æã¯ã
Mã®ãã©ã¡ãŒã¿ãŒåããFã®å¯Ÿå¿ãããã©ã¡ãŒã¿ãŒåã«ååšããŸãã - åç
§æž¡ããã©ã¡ãŒã¿ãŒããšã«ã
Mã®ãã©ã¡ãŒã¿ãŒåã¯ãFã®å¯Ÿå¿ãããã©ã¡ãŒã¿ãŒåãšåãã§ãã - æ»ãå€ã®åãå€ã®å Žåã
Fã®æ»ãå€ã®åããMã®æ»ãå€ã®åãžã® IDãæé»çãªåç §ããŸãã¯æé»çãªãã€ã³ã¿ãŒå€æãååšããŸãã - æ»ãå€ã®åãåç
§åã®å Žåã
refã®æ»ãå€ã®åããã³F修食åã¯ãrefã®æ»ãå€ã®åããã³M修食åãšåãã§ãã -
Mã®åŒã³åºãèŠåã¯ãFã®åŒã³åºãèŠåãšåãã§ãã -
Mã¯éçã¡ãœããã§ãã
次ã«ç€ºãããã«ãã¿ãŒã²ãããã¡ãœãã ã°ã«ãŒã Eã§ããunary_expressionãããéåžžã®åœ¢åŒ (§12.6.4.2) ã§é©çšå¯èœãªã¡ãœãããå°ãªããšã 1 ã€å«ãŸããŠãã Eå ŽåFãäºææ§ã®ãã颿°ãã€ã³ã¿ãŒåãžã®æé»çãªå€æã FååšããŸã (§12.6.4.2)ã
- ãã©ãŒã
Mã®ã¡ãœããåŒã³åºãã«å¯Ÿå¿ãã 1 ã€ã®ã¡ãœããE(A)ãéžæãããæ¬¡ã®å€æŽãå ããããŸãã-
AåŒæ°ãªã¹ãã¯åŒã®ãªã¹ãã§ããããããã倿°ãšããŠåé¡ãããã®å¯Ÿå¿ããFã®åãšä¿®é£Ÿåãå«ãŸããŸãã - åè£ã¡ãœããã¯ãéåžžã®åœ¢åŒã§é©çšã§ããã¡ãœããã®ã¿ã§ãå±éããã圢åŒã§ã¯é©çšã§ããŸããã
- åè£ã¡ãœããã¯ãéçãªã¡ãœããã®ã¿ã§ãã
-
- ãªãŒããŒããŒã解決ã®ã¢ã«ãŽãªãºã ã§ãšã©ãŒãçºçããå Žåã¯ãã³ã³ãã€ã«æãšã©ãŒãçºçããŸãã ãã以å€ã®å Žåãã¢ã«ãŽãªãºã ã¯ã
Mãšåãæ°ã®ãã©ã¡ãŒã¿ãŒãæã€F1 ã€ã®æé©ãªæ¹æ³ãçæãã倿ãååšãããšèŠãªãããŸãã - éžæããã¡ãœãã
Mã¯ã(äžèšã§å®çŸ©ãã) 颿°ãã€ã³ã¿ãŒåã®Fãšäºææ§ãããå¿ èŠããããŸãã ãã以å€ã®å Žåã¯ãã³ã³ãã€ã«æãšã©ãŒãçºçããŸãã - 倿ã®çµæã¯ã
Fåã®é¢æ°ãã€ã³ã¿ãŒã§ãã
å埩åã§ã¯ãããŒã«ã«ãŸãã¯ãã©ã¡ãŒã¿ãŒã®ã¢ãã¬ã¹ãååŸããã®ã¯ã³ã³ãã€ã«æãšã©ãŒã§ãã
24.6.6 ãã€ã³ã¿ãŒã®ã€ã³ã¯ãªã¡ã³ããšãã¯ãªã¡ã³ã
å®å
šã§ãªãã³ã³ããã¹ãã§ã¯ã ++ æŒç®åãš -- æŒç®å (§12.8.16 ãã㳠§12.9.7) ãããã¹ãŠã®åã®ããŒã¿ ãã€ã³ã¿ãŒå€æ°ã«é©çšã§ããŸãã ãããã®æŒç®åãå funcptr_type ãŸã㯠voidptr_typeã®å€æ°ã«é©çšãããã³ã³ãã€ã«æãšã©ãŒã§ãã ãããã£ãŠããã¹ãŠã®ããŒã¿ ãã€ã³ã¿ãŒå T*ã«ã€ããŠãæ¬¡ã®æŒç®åãæé»çã«å®çŸ©ãããŸãã
T* operator ++(T* x);
T* operator --(T* x);
æŒç®åã¯ããããã x+1 ããã³ x-1 ãšåãçµæãçæããŸã (§24.6.7)ã ã€ãŸãã T*åã®ããŒã¿ ãã€ã³ã¿ãŒå€æ°ã®å Žåã ++ æŒç®åã¯å€æ°ã«å«ãŸããã¢ãã¬ã¹ã« sizeof(T) ã远å ãã -- æŒç®åã¯å€æ°ã«å«ãŸããã¢ãã¬ã¹ãã sizeof(T) ãæžç®ããŸãã
ãã€ã³ã¿ãŒã®ã€ã³ã¯ãªã¡ã³ããŸãã¯ãã¯ãªã¡ã³ãæäœããã€ã³ã¿ãŒåã®ãã¡ã€ã³ããªãŒããŒãããŒããå Žåãçµæã¯å®è£ å®çŸ©ã§ãããäŸå€ã¯å¿ èŠãããŸããã
24.6.7 ãã€ã³ã¿ãŒã®ç®è¡æŒç®
å®å
šã§ãªãã³ã³ããã¹ãã§ã¯ããã¹ãŠã®ããŒã¿ ãã€ã³ã¿ãŒåã®å€ã« + æŒç®å (§12.13.5) ãš - æŒç®å (§12.13.6) ãé©çšã§ããŸãã ãããã®æŒç®åãfuncptr_typeåãŸãã¯voidptr_typeåã®å€ã«é©çšãããã³ã³ãã€ã«æãšã©ãŒã§ãã ãããã£ãŠããã€ã³ã¿ãŒå T*ããšã«ãæ¬¡ã®æŒç®åãæé»çã«å®çŸ©ãããŸãã
T* operator +(T* x, int y);
T* operator +(T* x, uint y);
T* operator +(T* x, nint y);
T* operator +(T* x, nuint y);
T* operator +(T* x, long y);
T* operator +(T* x, ulong y);
T* operator +(int x, T* y);
T* operator +(uint x, T* y);
T* operator +(nint x, T* y);
T* operator +(nuint x, T* y);
T* operator +(long x, T* y);
T* operator +(ulong x, T* y);
T* operator â(T* x, int y);
T* operator â(T* x, uint y);
T* operator -(T* x, nint y);
T* operator -(T* x, nuint y);
T* operator â(T* x, long y);
T* operator â(T* x, ulong y);
long operator â(T* x, T* y);
ãã€ãã£ãæŽæ° (§8.3.6) ãªãã»ããã䜿çšãããã€ã³ã¿ãŒã®å ç®ãŸãã¯æžç®ã«ã¯ãå®çŸ©æžã¿ã®æŒç®åã¯ãããŸããã 代ããã«ã nint å€ãš nuint å€ããããã long ãš ulongã«ææ Œããããããã®åã«å¯ŸããŠå®çŸ©æžã¿ã®æŒç®åã䜿çšããŠãã€ã³ã¿ãŒã®ç®è¡æŒç®ãè¡ããŸãã
ããŒã¿ ãã€ã³ã¿ãŒåPã®åŒT*ãšãåNãintãuintãnintãnuintããŸãã¯longã®åŒulongãæå®ãããšãåŒP + NããN + Pã«ãã£ãŠæå®ãããã¢ãã¬ã¹ã«T*ã远å ããçµæN * sizeof(T)åã®ãã€ã³ã¿ãŒå€ãèšç®Pã åæ§ã«ãåŒP â Nã¯ãT*ã«ãã£ãŠæå®ãããã¢ãã¬ã¹ããN * sizeof(T)ãæžç®ããçµæã®åPã®ãã€ã³ã¿ãŒå€ãèšç®ããŸãã
ããŒã¿ ãã€ã³ã¿ãŒåPã®QãšT*ã® 2 ã€ã®åŒãæå®ãããšãåŒP â QPã«ãã£ãŠæå®ãããã¢ãã¬ã¹ãšQã®å·®ãèšç®ãããã®å·®ãsizeof(T)ã§é€ç®ããŸãã çµæã®åã¯åžžã« longã å®éã«ã¯ã P - Q 㯠((long)(P) - (long)(Q)) / sizeof(T)ãšããŠèšç®ãããŸãã
äŸ:
class Test { static void Main() { unsafe { int* values = stackalloc int[20]; int* p = &values[1]; int* q = &values[15]; Console.WriteLine($"p - q = {p - q}"); Console.WriteLine($"q - p = {q - p}"); } } }åºåãçæããŸãã
p - q = -14 q - p = 14end ã®äŸ
ãã€ã³ã¿ãŒã®ç®è¡æŒç®ããã€ã³ã¿ãŒåã®ãã¡ã€ã³ããªãŒããŒãããŒããå Žåãçµæã¯å®è£ å®çŸ©ã§ãããäŸå€ã¯å¿ èŠãããŸããã
24.6.8 ãã€ã³ã¿ãŒã®æ¯èŒ
å®å
šã§ãªãã³ã³ããã¹ãã§ã¯ã ==ã !=ã <ã >ã <=ãããã³ >= æŒç®å (§12.15) ã¯ããã¹ãŠã® dataptr_typeã®å€ãšãdataptr_typeå€ã®ã³ããŒã§ãããã¹ãŠã® voidptr_types ã®å€ã«å®å
š ã« é©çšã§ããŸãã ãã€ã³ã¿ãŒæ¯èŒæŒç®åã¯æ¬¡ã®ãšããã§ãã
bool operator ==(void* x, void* y);
bool operator !=(void* x, void* y);
bool operator <(void* x, void* y);
bool operator >(void* x, void* y);
bool operator <=(void* x, void* y);
bool operator >=(void* x, void* y);
ãã€ã³ã¿ãŒåãã void* åãžã®æé»çãªå€æãååšããããããã€ã³ã¿ãŒåã®ãªãã©ã³ãã¯ããããã®æŒç®åã䜿çšããŠæ¯èŒã§ããŸãã æ¯èŒæŒç®åã¯ã2 ã€ã®ãªãã©ã³ãã«ãã£ãŠæå®ãããã¢ãã¬ã¹ã笊å·ãªãæŽæ°ã§ãããã®ããã«æ¯èŒããŸãã ãã ãã funcptr_types ã®å€ãŸãã¯ãã®ã³ã㌠void* æ¯èŒãããšãã®åäœã¯æªå®çŸ©ã§ãã
泚: äžéšã®ãã©ãããã©ãŒã ã§ã¯ãç¹å®ã®ã¡ãœããã®ã¢ãã¬ã¹ãè€æ°åååŸããããšãçµæãç°ãªãå¯èœæ§ãããããããã®æ¯èŒãä¿¡é Œæ§ã«æ¬ ããå¯èœæ§ããããŸãã æ³šé
24.6.9 sizeof æŒç®å
ç¹å®ã®å (§12.8.19) ã®å Žåã sizeof æŒç®åã¯å®æ° int å€ãçæããŸãã ãã®ä»ã®ãã¹ãŠã®åã§ã¯ã sizeof æŒç®åã®çµæã¯å®è£
å®çŸ©ã§ããã宿°ã§ã¯ãªãå€ãšããŠåé¡ãããŸãã
ã¡ã³ããŒãæ§é äœã«ããã¯ãããé åºã¯æå®ãããŠããŸããã
é 眮ã®ç®çã§ãæ§é äœã®å é ãæ§é äœå ãããã³æ§é äœã®æ«å°Ÿã«ãååã®ãªãããã£ã³ã°ãååšããå¯èœæ§ããããŸãã ããã£ã³ã°ãšããŠäœ¿çšããããããã®å 容ã¯äžç¢ºå®ã§ãã
æ§é äœåãæã€ãªãã©ã³ãã«é©çšãããšãçµæã¯ãåã蟌ã¿ãå«ãããã®åã®å€æ°å ã®åèšãã€ãæ°ã«ãªããŸãã
24.7 åºå®ã¹ããŒãã¡ã³ã
å®å šã§ãªãã³ã³ããã¹ãã§ã¯ã embedded_statement (§13.1) ã®éçšç°å¢ã§ã¯ã远å ã®ã³ã³ã¹ãã©ã¯ã (åºå®ã¹ããŒãã¡ã³ã) ãèš±å¯ãããŸããåºå®ã¹ããŒãã¡ã³ãã¯ãç§»åå¯èœãªå€æ°ã "ä¿®æ£" ããããã«äœ¿çšããããã®ã¢ãã¬ã¹ã¯ã¹ããŒãã¡ã³ãã®æéäžäžå®ã®ãŸãŸã§ãã
fixed_statement
: 'fixed' '(' pointer_type fixed_pointer_declarators ')' embedded_statement
;
fixed_pointer_declarators
: fixed_pointer_declarator (',' fixed_pointer_declarator)*
;
fixed_pointer_declarator
: identifier '=' fixed_pointer_initializer
;
fixed_pointer_initializer
: '&' variable_reference
| expression
;
å fixed_pointer_declarator ã¯ãæå®ããã pointer_type ã®ããŒã«ã«å€æ°ã宣èšãã察å¿ãã fixed_pointer_initializerã«ãã£ãŠèšç®ãããã¢ãã¬ã¹ã䜿çšããŠãã®ããŒã«ã«å€æ°ãåæåããŸãã
pointer_type 㯠funcptr_typeãããŸããã åºå®ã¹ããŒãã¡ã³ãã§å®£èšãããããŒã«ã«å€æ°ã«ã¯ããã®å€æ°ã®å®£èšã®å³åŽã§çºçãã fixed_pointer_initializerãšãåºå®ã¹ããŒãã¡ã³ãã® embedded_statement ã§ã¢ã¯ã»ã¹ã§ããŸãã åºå®ã¹ããŒãã¡ã³ãã«ãã£ãŠå®£èšãããããŒã«ã«å€æ°ã¯ãèªã¿åãå°çšãšèŠãªãããŸãã ã³ã³ãã€ã«æãšã©ãŒã¯ãåã蟌ã¿ã¹ããŒãã¡ã³ãã (代å
¥æŒç®åãŸã㯠++ æŒç®åãš -- æŒç®åã䜿çšããŠ) ãã®ããŒã«ã«å€æ°ã倿Žããããšããå ŽåããŸãã¯åç
§ãã©ã¡ãŒã¿ãŒãŸãã¯åºåãã©ã¡ãŒã¿ãŒãšããŠæž¡ãããšããå Žåã«çºçããŸãã
ãã£ããã£ãããããŒã«ã«å€æ° (§12.22.6.2)ãå€ãã©ã¡ãŒã¿ãŒããŸãã¯ãã©ã¡ãŒã¿ãŒ ã³ã¬ã¯ã·ã§ã³ã fixed_pointer_initializerã§äœ¿çšãããšãšã©ãŒã«ãªããŸãã fixed_pointer_initializerã«ã¯ã次ã®ãããããæå®ã§ããŸãã
- ããŒã¯ã³ "
&" ã®åŸã«ãåã®ç§»åå¯èœå€æ° (§24.4) ãžã®variable_reference (T) ãç¶ããŸãããã ããåT*ã¯ãfixedã¹ããŒãã¡ã³ãã§æå®ããããã€ã³ã¿ãŒåã«æé»çã«å€æã§ããŸãã ãã®å Žåãåæååã¯æå®ããã倿°ã®ã¢ãã¬ã¹ãèšç®ããŸãã倿°ã¯ãåºå®ã¹ããŒãã¡ã³ãã®æéäžãåºå®ã¢ãã¬ã¹ã®ãŸãŸã§ããããšãä¿èšŒãããŸããTããããŒãžãåã®å Žåã¯ãèŠåãçæãããŸãã - åããåºå®ã¹ããŒãã¡ã³ãã§æå®ããããã€ã³ã¿ãŒåã«æé»çã«å€æã§ããå Žåã
Tåã®èŠçŽ ãæã€array_typeã®åŒã ãã®å Žåãåæååã¯é åå ã®æåã®èŠçŽ ã®ã¢ãã¬ã¹ãèšç®ããŸããé åå šäœã¯ãfixedã¹ããŒãã¡ã³ãã®éãåºå®ã¢ãã¬ã¹ã®ãŸãŸã§ããããšãä¿èšŒãããŸãã é ååŒãnullã®å ŽåããŸãã¯é åã«èŠçŽ ã 0 ã®å Žåãåæåå㯠0 ã«çããã¢ãã¬ã¹ãèšç®ããŸããTããããŒãžãåã®å Žåã¯ãèŠåãçæãããŸãã -
stringåããchar*ã¹ããŒãã¡ã³ãã§æå®ããããã€ã³ã¿ãŒåã«æé»çã«å€æã§ããå Žåãfixedåã®åŒã ãã®å Žåãåæååã¯æååå ã®æåã®æåã®ã¢ãã¬ã¹ãèšç®ããæååå šäœãfixedã¹ããŒãã¡ã³ãã®éãåºå®ã¢ãã¬ã¹ã®ãŸãŸã§ããããšãä¿èšŒãããŸãã æåååŒãfixedãããŠããå Žåãnullã¹ããŒãã¡ã³ãã®åäœã¯å®è£ ã§å®çŸ©ãããŸãã - ã·ã°ãã㣠ã«äžèŽããã¢ã¯ã»ã¹å¯èœãªã¡ãœãããŸãã¯ã¢ã¯ã»ã¹å¯èœãªæ¡åŒµã¡ãœãããååšããå Žåã
stringãŸãã¯ref [readonly] T GetPinnableReference()以å€ã®åã®åŒãTã¯unmanaged_typeã§ãããT*ã¯fixedã¹ããŒãã¡ã³ãã§æå®ããããã€ã³ã¿ãŒåã«æé»çã«å€æã§ããŸãã ãã®å Žåãåæååã¯è¿ããã倿°ã®ã¢ãã¬ã¹ãèšç®ãããã®å€æ°ã¯ãfixedã¹ããŒãã¡ã³ãã®æéäžãåºå®ã¢ãã¬ã¹ã®ãŸãŸã§ããããšãä¿èšŒãããŸãã ãªãŒããŒããŒã解決 (GetPinnableReference()) ã«ãã£ãŠé¢æ°ã¡ã³ããŒã 1 ã€ã ãçæããããã®é¢æ°ã¡ã³ããŒãäžèšã®æ¡ä»¶ãæºããå Žåã¯ãfixedã¡ãœããã ã¹ããŒãã¡ã³ãã§äœ¿çšã§ããŸããGetPinnableReferenceã¡ãœããã¯ããã³çãããããŒã¿ããªãå Žåã«System.Runtime.CompilerServices.Unsafe.NullRef<T>()ããè¿ããããªã©ã0 ã«çããã¢ãã¬ã¹ãžã®åç §ãè¿ãå¿ èŠããããŸãã - åºå®ãµã€ãºã®ãããã¡ãŒ ã¡ã³ããŒã®åãã ã¹ããŒãã¡ã³ãã§æå®ããããã€ã³ã¿ãŒåã«æé»çã«å€æã§ããå Žåã«ãç§»åå¯èœãªå€æ°ã®åºå®ãµã€ãºãããã¡ãŒ ã¡ã³ããŒãåç
§ããsimple_nameãŸãã¯
fixedã ãã®å Žåãåæååã¯åºå®ãµã€ãº ãããã¡ãŒ (§24.8.3) ã®æåã®èŠçŽ ãžã®ãã€ã³ã¿ãŒãèšç®ããåºå®ãµã€ãº ãããã¡ãŒã¯ãfixedã¹ããŒãã¡ã³ãã®éãåºå®ã¢ãã¬ã¹ã«æ®ããŸãã
fixed_pointer_initializerã«ãã£ãŠèšç®ãããåã¢ãã¬ã¹ã«ã€ããŠãfixed ã¹ããŒãã¡ã³ãã¯ãfixed ã¹ããŒãã¡ã³ãã®æéäžãã¢ãã¬ã¹ã«ãã£ãŠåç
§ããã倿°ãã¬ããŒãž ã³ã¬ã¯ã¿ãŒã«ããåé
眮ãŸãã¯ç Žæ£ã®å¯Ÿè±¡ã«ãªããªãããšãä¿èšŒããŸãã
äŸ: fixed_pointer_initializer ã«ãã£ãŠèšç®ãããã¢ãã¬ã¹ããªããžã§ã¯ãã®ãã£ãŒã«ããŸãã¯é åã€ã³ã¹ã¿ã³ã¹ã®èŠçŽ ãåç §ããå Žåãåºå®ã¹ããŒãã¡ã³ãã¯ãã¹ããŒãã¡ã³ãã®æå¹æéäžã«ãå«ãŸãããªããžã§ã¯ã ã€ã³ã¹ã¿ã³ã¹ãåé 眮ãŸãã¯ç Žæ£ãããªãããšãä¿èšŒããŸãã end ã®äŸ
åºå®ã¹ããŒãã¡ã³ãã«ãã£ãŠäœæããããã€ã³ã¿ãŒãããããã®ã¹ããŒãã¡ã³ãã®å®è¡ãè¶ ããŠåç¶ããªãããã«ããã®ã¯ããã°ã©ãã®è²¬ä»»ã§ãã
äŸ:
fixedã¹ããŒãã¡ã³ãã«ãã£ãŠäœæããããã€ã³ã¿ãŒãå€éš API ã«æž¡ãããå ŽåãAPI ããããã®ãã€ã³ã¿ãŒã®ã¡ã¢ãªãä¿æããªãããã«ããã®ã¯ããã°ã©ãã®è²¬ä»»ã§ãã end ã®äŸ
åºå®ãªããžã§ã¯ãã¯ãããŒãã®æçåãåŒãèµ·ããå¯èœæ§ããããŸã (ç§»åã§ããªããã)ã ãã®ããããªããžã§ã¯ãã¯ã絶察ã«å¿ èŠãªå Žåã«ã®ã¿åºå®ããå¯èœãªéãæçã®æéã ãåºå®ããå¿ èŠããããŸãã
äŸ: äŸ
class Test { static int x; int y; unsafe static void F(int* p) { *p = 1; } static void Main() { Test t = new Test(); int[] a = new int[10]; unsafe { fixed (int* p = &x) F(p); fixed (int* p = &t.y) F(p); fixed (int* p = &a[0]) F(p); fixed (int* p = a) F(p); } } }ã¯ã
fixedã¹ããŒãã¡ã³ãã®ããã€ãã®äœ¿ç𿹿³ã瀺ããŠããŸãã æåã®ã¹ããŒãã¡ã³ãã¯éçãã£ãŒã«ãã®ã¢ãã¬ã¹ãä¿®æ£ããŠååŸãã2 çªç®ã®ã¹ããŒãã¡ã³ãã¯ã€ã³ã¹ã¿ã³ã¹ ãã£ãŒã«ãã®ã¢ãã¬ã¹ãä¿®æ£ããŠååŸãã3 çªç®ã®ã¹ããŒãã¡ã³ãã¯é åèŠçŽ ã®ã¢ãã¬ã¹ãä¿®æ£ããŠååŸããŸãã ãããã®å Žåãã倿°ã¯ãã¹ãŠç§»åå¯èœãªå€æ°ãšããŠåé¡ããããããéåžžã®&æŒç®åã䜿çšããã®ã¯ãšã©ãŒã§ãããäžèšã®äŸã® 3 çªç®ãš 4 çªç®ã®
fixedã¹ããŒãã¡ã³ãã§ã¯ãåãçµæãçæãããŸãã äžè¬ã«ãé åã€ã³ã¹ã¿ã³ã¹aã®å Žåãa[0]ã¹ããŒãã¡ã³ãã§fixedãæå®ããããšã¯ãåã«aãæå®ããã®ãšåãã§ããend ã®äŸ
å®å
šã§ãªãã³ã³ããã¹ãã§ã¯ã1 次å
é
åã®é
åèŠçŽ ã¯ãã€ã³ããã¯ã¹ã® 0 ããå§ãŸããã€ã³ããã¯ã¹ Length â 1ã§çµããã€ã³ããã¯ã¹ã®é åºã§æ ŒçŽãããŸãã 倿¬¡å
é
åã®å Žåãé
åèŠçŽ ã¯ãå³ç«¯ã®æ¬¡å
ã®ã€ã³ããã¯ã¹ãæåã«å¢å ããæ¬¡ã«æ¬¡ã®å·Šã®æ¬¡å
ãå·Šã«å¢å ããããã«æ ŒçŽãããŸãã
é
åã€ã³ã¹ã¿ã³ã¹ fixedãžã®ãã€ã³ã¿ãŒpãååŸããa ã¹ããŒãã¡ã³ãå
ã§ãpããp + a.Length - 1ãŸã§ã®ãã€ã³ã¿ãŒå€ã¯ãé
åå
ã®èŠçŽ ã®ã¢ãã¬ã¹ã衚ããŸãã åæ§ã«ã p[0] ãã p[a.Length - 1] ãŸã§ã®å€æ°ã¯ãå®éã®é
åèŠçŽ ã衚ããŸãã é
åãæ ŒçŽããæ¹æ³ãèãããšã次å
ã®é
åã¯ç·åœ¢ã§ãããã®ããã«æ±ãããšãã§ããŸãã
äŸ:
class Test { static void Main() { int[,,] a = new int[2,3,4]; unsafe { fixed (int* p = a) { for (int i = 0; i < a.Length; ++i) // treat as linear { p[i] = i; } } } for (int i = 0; i < 2; ++i) { for (int j = 0; j < 3; ++j) { for (int k = 0; k < 4; ++k) { Console.Write($"[{i},{j},{k}] = {a[i,j,k],2} "); } Console.WriteLine(); } } } }åºåãçæããŸãã
[0,0,0] = 0 [0,0,1] = 1 [0,0,2] = 2 [0,0,3] = 3 [0,1,0] = 4 [0,1,1] = 5 [0,1,2] = 6 [0,1,3] = 7 [0,2,0] = 8 [0,2,1] = 9 [0,2,2] = 10 [0,2,3] = 11 [1,0,0] = 12 [1,0,1] = 13 [1,0,2] = 14 [1,0,3] = 15 [1,1,0] = 16 [1,1,1] = 17 [1,1,2] = 18 [1,1,3] = 19 [1,2,0] = 20 [1,2,1] = 21 [1,2,2] = 22 [1,2,3] = 23end ã®äŸ
äŸ: 次ã®ã³ãŒãå
class Test { unsafe static void Fill(int* p, int count, int value) { for (; count != 0; count--) { *p++ = value; } } static void Main() { int[] a = new int[100]; unsafe { fixed (int* p = a) Fill(p, 100, -1); } } }
fixedã¹ããŒãã¡ã³ãã¯ããã€ã³ã¿ãŒãåãåãã¡ãœããã«ã¢ãã¬ã¹ãæž¡ãããšãã§ããããã«ãé åãä¿®æ£ããããã«äœ¿çšãããŸããend ã®äŸ
æååã€ã³ã¹ã¿ã³ã¹ãä¿®æ£ããããšã«ãã£ãŠçæããã char* å€ã¯ãåžžã« null ã§çµããæååãæããŸãã æååã€ã³ã¹ã¿ã³ã¹pãžã®ãã€ã³ã¿ãŒsãååŸããåºå®ã¹ããŒãã¡ã³ãå
ã§ã¯ãpããp + s.Length â 1ãŸã§ã®ãã€ã³ã¿ãŒå€ã¯æååå
ã®æåã®ã¢ãã¬ã¹ã衚ãããã€ã³ã¿ãŒå€p + s.Lengthã¯åžžã« null æå (å€ '\0' ã®æå) ãæããŸãã
äŸ:
class Test { static string name = "xx"; unsafe static void F(char* p) { for (int i = 0; p[i] != '\0'; ++i) { System.Console.WriteLine(p[i]); } } static void Main() { unsafe { fixed (char* p = name) F(p); fixed (char* p = "xx") F(p); } } }end ã®äŸ
äŸ: 次ã®ã³ãŒãã¯ãarray_typeãŸãã¯ä»¥å€ã®åã®åŒãæã€
stringã瀺ããŠããŸããpublic class C { private int _value; public C(int value) => _value = value; public ref int GetPinnableReference() => ref _value; } public class Test { unsafe private static void Main() { C c = new C(10); fixed (int* p = c) { // ... } } }å
Cã«ã¯ãæ£ããã·ã°ããã£ãæã€ã¢ã¯ã»ã¹å¯èœãªGetPinnableReferenceã¡ãœããããããŸããfixedã¹ããŒãã¡ã³ãã§ã¯ãref intã§åŒã³åºããããšãã«ãã®ã¡ãœããããè¿ãããcã䜿çšããŠãint*ãã€ã³ã¿ãŒã®pãåæåããŸãã end ã®äŸ
åºå®ãã€ã³ã¿ãŒã䜿çšããŠãããŒãžãåã®ãªããžã§ã¯ãã倿Žãããšãæªå®çŸ©ã®åäœãçºçããå¯èœæ§ããããŸãã
泚: ããšãã°ãæååã¯äžå€ã§ãããããåºå®æååãžã®ãã€ã³ã¿ãŒã«ãã£ãŠåç §ãããæåã倿Žãããªãããã«ããã®ã¯ããã°ã©ãã®è²¬ä»»ã§ãã æ³šé
泚: æååã®èªå null çµç«¯ã¯ã"C ã¹ã¿ã€ã«" æååãå¿ èŠãšããå€éš API ãåŒã³åºããšãã«ç¹ã«äŸ¿å©ã§ãã ãã ããæååã€ã³ã¹ã¿ã³ã¹ã«ã¯ null æåãå«ããã®ãèš±å¯ãããŠããããšã«æ³šæããŠãã ããã ãã®ãã㪠null æåãååšããå Žåãnull ã§çµãã
char*ãšããŠæ±ããããšãæååã¯åãæšãŠãããç¶æ ã§è¡šç€ºãããŸãã æ³šé
24.8 åºå®ãµã€ãºãããã¡ãŒ
24.8.1 å šè¬
åºå®ãµã€ãº ãããã¡ãŒã¯ã"C ã¹ã¿ã€ã«" ã€ã³ã©ã€ã³é åãæ§é äœã®ã¡ã³ããŒãšããŠå®£èšããããã«äœ¿çšãããäž»ã«ã¢ã³ãããŒãž API ãšã®ã€ã³ã¿ãŒãã§ã€ã¹ã«åœ¹ç«ã¡ãŸãã
24.8.2 åºå®ãµã€ãºã®ãããã¡ãŒå®£èš
åºå®ãµã€ãºãããã¡ãŒã¯ãç¹å®ã®åã®å€æ°ã®åºå®é·ãããã¡ãŒã®ã¹ãã¬ãŒãžã衚ãã¡ã³ããŒã§ãã åºå®ãµã€ãº ãããã¡ãŒå®£èšã§ã¯ãç¹å®ã®èŠçŽ åã® 1 ã€ä»¥äžã®åºå®ãµã€ãº ãããã¡ãŒãå°å ¥ãããŸãã
泚: é åãšåæ§ã«ãåºå®ãµã€ãºã®ãããã¡ãŒã¯èŠçŽ ãå«ããã®ãšããŠèããããšãã§ããŸãã ãã®ãããé åã«å¯ŸããŠå®çŸ©ãããŠãã èŠçŽ å ãšããçšèªã¯ãåºå®ãµã€ãºã®ãããã¡ãŒã§ã䜿çšãããŸãã æ³šé
åºå®ãµã€ãºãããã¡ãŒã¯æ§é äœå®£èšã§ã®ã¿èš±å¯ãããå®å šã§ãªãã³ã³ããã¹ãã§ã®ã¿çºçããå¯èœæ§ããããŸã (§24.2)ã
fixed_size_buffer_declaration
: attributes? fixed_size_buffer_modifier* 'fixed' buffer_element_type
fixed_size_buffer_declarators ';'
;
fixed_size_buffer_modifier
: 'new'
| 'public'
| 'internal'
| 'private'
| 'unsafe'
;
buffer_element_type
: type
;
fixed_size_buffer_declarators
: fixed_size_buffer_declarator (',' fixed_size_buffer_declarator)*
;
fixed_size_buffer_declarator
: identifier '[' constant_expression ']'
;
åºå®ãµã€ãºã®ãããã¡ãŒå®£èšã«ã¯ãäžé£ã®å±æ§ (§23)ã new 修食å (§15.3.5)ãæ§é äœã¡ã³ã㌠(§16.8.3) ã«èš±å¯ãããŠãã宣èšãããã¢ã¯ã»ã·ããªãã£ã®ããããã«å¯Ÿå¿ããã¢ã¯ã»ã·ããªãã£ä¿®é£Ÿåãããã³ unsafe 修食å (§24.2) ãå«ããããšãã§ããŸãã 屿§ãšä¿®é£Ÿåã¯ãåºå®ãµã€ãºãããã¡ãŒå®£èšã«ãã£ãŠå®£èšããããã¹ãŠã®ã¡ã³ããŒã«é©çšãããŸãã åºå®ãµã€ãºã®ãããã¡ãŒå®£èšã§åã修食åãè€æ°ååºçŸããã®ã¯ãšã©ãŒã§ãã
åºå®ãµã€ãºã®ãããã¡ãŒå®£èšã«ã¯ã static 修食åãå«ããããŸããã
åºå®ãµã€ãºã®ãããã¡ãŒå®£èšã®ãããã¡ãŒèŠçŽ åã¯ã宣èšã«ãã£ãŠå°å
¥ããããããã¡ãŒã®èŠçŽ åãæå®ããŸãã ãããã¡ãŒèŠçŽ ã®åã¯ãå®çŸ©æžã¿ã®å sbyteã byteã shortã ushortã intã uintã nintã nuintã longã ulongã charã floatã doubleããŸã㯠boolã®ããããã«ãªããŸãã
ãããã¡ãŒèŠçŽ ã®åã®åŸã«ãåºå®ãµã€ãºã®ãããã¡ãŒå®£èšåã®äžèЧãç¶ãããããããæ°ããã¡ã³ããŒãå°å
¥ããŸãã åºå®ãµã€ãºã®ãããã¡ãŒå®£èšåã¯ãã¡ã³ããŒã«ååãä»ããèå¥åã®åŸã«ã [ ããã³ ] ããŒã¯ã³ã§å²ãŸãã宿°åŒã§æ§æãããŸãã 宿°åŒã¯ããã®åºå®ãµã€ãºã®ãããã¡ãŒå®£èšåã«ãã£ãŠå°å
¥ãããã¡ã³ããŒå
ã®èŠçŽ ã®æ°ã衚ããŸãã 宿°åŒã®åã¯ã intåã«æé»çã«å€æã§ããå€ã¯ 0 以å€ã®æ£ã®æŽæ°ã§ããå¿
èŠããããŸãã
åºå®ãµã€ãºã®ãããã¡ãŒã®èŠçŽ ã¯ãã¡ã¢ãªå ã«é çªã«é 眮ããå¿ èŠããããŸãã
è€æ°ã®åºå®ãµã€ãº ãããã¡ãŒã宣èšããåºå®ãµã€ãº ãããã¡ãŒå®£èšã¯ãåã屿§ãšèŠçŽ åãæã€ 1 ã€ã®åºå®ãµã€ãº ãããã¡ãŒå®£èšã®è€æ°ã®å®£èšãšåãã§ãã
äŸ:
unsafe struct A { public fixed int x[5], y[10], z[100]; }äžèšã®åŒã¯ã次ã®åŒãšåãã§ãã
unsafe struct A { public fixed int x[5]; public fixed int y[10]; public fixed int z[100]; }end ã®äŸ
24.8.3 åŒã®åºå®ãµã€ãº ãããã¡ãŒ
åºå®ãµã€ãºã®ãããã¡ãŒ ã¡ã³ããŒã®ã¡ã³ããŒåç § (§12.5) ã¯ããã£ãŒã«ãã®ã¡ã³ããŒåç §ãšãŸã£ããåãããã«åŠçãããŸãã
åºå®ãµã€ãºã®ãããã¡ãŒã¯ã simple_name (§12.8.4)ã member_access (§12.8.7)ããŸã㯠element_access (§12.8.12) ã䜿çšããŠåŒã§åç §ã§ããŸãã
åºå®ãµã€ãºã®ãããã¡ãŒ ã¡ã³ããŒãåçŽãªååãšããŠåç
§ãããŠããå Žåã广ã¯ãã©ãŒã this.Iã®ã¡ã³ã㌠ã¢ã¯ã»ã¹ãšåãã§ããããã§ã I ã¯åºå®ãµã€ãºã®ãããã¡ãŒ ã¡ã³ããŒã§ãã
E.Iãæé»çãªE.ã§ããå¯èœæ§ããããã©ãŒã this.ã®ã¡ã³ã㌠ã¢ã¯ã»ã¹ã§ã¯ãEãæ§é äœåã§ããããã®æ§é äœåã®Iã®ã¡ã³ããŒåç
§ã«ãã£ãŠåºå®ãµã€ãºã®ã¡ã³ããŒãèå¥ãããå ŽåãE.Iã¯è©äŸ¡ãããæ¬¡ã®ããã«åé¡ãããŸãã
- åŒ
E.Iãå®å šã§ãªãã³ã³ããã¹ãã§çºçããªãå Žåã¯ãã³ã³ãã€ã«æãšã©ãŒãçºçããŸãã -
Eãå€ãšããŠåé¡ããããšãã³ã³ãã€ã«æãšã©ãŒãçºçããŸãã - ãã以å€ã®å Žåã
Eãç§»åå¯èœãªå€æ° (§24.4) ã®å Žåã¯ã次ã®ããã«ãªããŸãã- åŒ
E.Iãfixed_pointer_initializer (§24.7) ã®å ŽåãåŒã®çµæã¯ãIã§Eåºå®ãµã€ãº ãããã¡ãŒ ã¡ã³ããŒã®æåã®èŠçŽ ãžã®ãã€ã³ã¿ãŒã«ãªããŸãã - ãã以å€ã®å ŽåãåŒ
E.Iããã©ãŒã ã®element_access (§12.8.12) å ã®primary_expression (E.I[J]) ã§ããå Žåã æ¬¡ã«ãE.Iã®çµæã¯ãPã§Iåºå®ãµã€ãº ãããã¡ãŒ ã¡ã³ããŒã®æåã®èŠçŽ ãžã®ãã€ã³ã¿ãŒ (E) ã«ãªããå€åŽã®element_accessã¯pointer_element_access (§24.6.4)P[J]ãšããŠè©äŸ¡ãããŸãã - ãã以å€ã®å Žåã¯ãã³ã³ãã€ã«æãšã©ãŒãçºçããŸãã
- åŒ
- ãã以å€ã®å Žåã
Eã¯åºå®å€æ°ãåç §ããåŒã®çµæã¯ãIã§Eåºå®ãµã€ãºãããã¡ãŒ ã¡ã³ããŒã®æåã®èŠçŽ ãžã®ãã€ã³ã¿ãŒã«ãªããŸãã çµæã¯S*åã§ãS ã¯Iã®èŠçŽ åã§ãããå€ãšããŠåé¡ãããŸãã
åºå®ãµã€ãº ãããã¡ãŒã®åŸç¶ã®èŠçŽ ã«ã¯ãæåã®èŠçŽ ããã®ãã€ã³ã¿ãŒæäœã䜿çšããŠã¢ã¯ã»ã¹ã§ããŸãã é åãžã®ã¢ã¯ã»ã¹ãšã¯ç°ãªããåºå®ãµã€ãºã®ãããã¡ãŒã®èŠçŽ ãžã®ã¢ã¯ã»ã¹ã¯å®å šã§ãªãæäœã§ãããç¯å²ã®ãã§ãã¯ã¯è¡ãããŸããã
äŸ: 次ã®äŸã§ã¯ãåºå®ãµã€ãºã®ãããã¡ãŒ ã¡ã³ããŒãæã€æ§é äœã宣èšããŠäœ¿çšããŸãã
unsafe struct Font { public int size; public fixed char name[32]; } class Test { unsafe static void PutString(string s, char* buffer, int bufSize) { int len = s.Length; if (len > bufSize) { len = bufSize; } for (int i = 0; i < len; i++) { buffer[i] = s[i]; } for (int i = len; i < bufSize; i++) { buffer[i] = (char)0; } } unsafe static void Main() { Font f; f.size = 10; PutString("Times New Roman", f.name, 32); } }end ã®äŸ
24.8.4 確å®ä»£å ¥ãã§ãã¯
åºå®ãµã€ãº ãããã¡ãŒã¯ãæç¢ºãªä»£å ¥ãã§ã㯠(§9.4) ã®å¯Ÿè±¡ã§ã¯ãªããåºå®ãµã€ãºã®ãããã¡ãŒ ã¡ã³ããŒã¯æ§é äœå倿°ã®æç¢ºãªä»£å ¥ãã§ãã¯ã®ããã«ç¡èŠãããŸãã
åºå®ãµã€ãº ãããã¡ãŒ ã¡ã³ããŒã®æãå€åŽã®æ ŒçŽæ§é äœå€æ°ãéç倿°ãã¯ã©ã¹ ã€ã³ã¹ã¿ã³ã¹ã®ã€ã³ã¹ã¿ã³ã¹å€æ°ããŸãã¯é åèŠçŽ ã§ããå Žåãåºå®ãµã€ãº ãããã¡ãŒã®èŠçŽ ã¯èªåçã«æ¢å®å€ (§9.3 ã«åæåãããŸãã ãã以å€ã®å Žåã¯ãåºå®ãµã€ãºãããã¡ãŒã®åæã³ã³ãã³ãã¯æªå®çŸ©ã§ãã
24.9 ã¹ã¿ãã¯ã®å²ãåœãŠ
æŒç®åã«é¢ããäžè¬çãªæ
å ±ã«ã€ããŠã¯ãstackalloc ãåç
§ããŠãã ããã ããã§ã¯ããã€ã³ã¿ãŒãçæãããã®æŒç®åã®æ©èœã«ã€ããŠèª¬æããŸãã
local_variable_typeããã€ã³ã¿ãŒå (§24.3) ãŸãã¯æšè« () ã§ããlocal_variable_declaration (§13.6.2) ã®åæååŒãšããŠstackalloc_expressionãçºçããå Žåãvarã®çµæã¯T*åã®ãã€ã³ã¿ãŒã§ãããTã¯stackalloc_expressionã®unmanaged_typeã§ãã ãã®å Žåãçµæã¯å²ãåœãŠããããããã¯ã®å
é ãžã®ãã€ã³ã¿ãŒã«ãªããŸãã
ãã以å€ã®å Žåã¯ãå®å šã§ãªãã³ã³ããã¹ãã® local_variable_declarations (§13.6.2) ãš stackalloc_expressions (§12.8.22) ã®ã»ãã³ãã£ã¯ã¹ããå®å šãªã³ã³ããã¹ãçšã«å®çŸ©ãããŠãããã®ã«åŸããŸãã
äŸ:
unsafe { // Memory uninitialized int* p1 = stackalloc int[3]; // Memory initialized int* p2 = stackalloc int[3] { -10, -15, -30 }; // Type int is inferred int* p3 = stackalloc[] { 11, 12, 13 }; // Cannot infer context, so pointer result assumed var p4 = stackalloc[] { 11, 12, 13 }; // Error; no conversion exists long* p5 = stackalloc[] { 11, 12, 13 }; // Converts 11 and 13, and returns long* long* p6 = stackalloc[] { 11, 12L, 13 }; // Converts all and returns long* long* p7 = stackalloc long[] { 11, 12, 13 }; }end ã®äŸ
stackallocåã®é
åãŸã㯠Span<T>'ed ãããã¯ãžã®ã¢ã¯ã»ã¹ãšã¯ç°ãªãããã€ã³ã¿ãŒåã® stackalloc'ed ãããã¯ã®èŠçŽ ãžã®ã¢ã¯ã»ã¹ã¯å®å
šã§ãªãæäœã§ãããç¯å²ã®ãã§ãã¯ã¯è¡ãããŸããã
äŸ: 次ã®ã³ãŒãå
class Test { static string IntToString(int value) { if (value == int.MinValue) { return "-2147483648"; } int n = value >= 0 ? value : -value; unsafe { char* buffer = stackalloc char[16]; char* p = buffer + 16; do { *--p = (char)(n % 10 + '0'); n /= 10; } while (n != 0); if (value < 0) { *--p = '-'; } return new string(p, 0, (int)(buffer + 16 - p)); } } static void Main() { Console.WriteLine(IntToString(12345)); Console.WriteLine(IntToString(-999)); } }
stackallocã¡ãœããã§ã¯ãIntToStringåŒã䜿çšããŠãã¹ã¿ãã¯ã« 16 æåã®ãããã¡ãŒãå²ãåœãŠãŸãã ã¡ãœããããå¶åŸ¡ãæ»ããšããããã¡ãŒã¯èªåçã«ç Žæ£ãããŸãããã ãã
IntToStringã¯ã»ãŒã ã¢ãŒãã§æžãæããããšãã§ããŸããã€ãŸãããã€ã³ã¿ãŒã䜿çšããã«ã次ã®ããã«æžãæããããšãã§ããŸããclass Test { static string IntToString(int value) { if (value == int.MinValue) { return "-2147483648"; } int n = value >= 0 ? value : -value; Span<char> buffer = stackalloc char[16]; int idx = 16; do { buffer[--idx] = (char)(n % 10 + '0'); n /= 10; } while (n != 0); if (value < 0) { buffer[--idx] = '-'; } return buffer.Slice(idx).ToString(); } }end ã®äŸ
æ¡ä»¶ä»ãã§èŠç¯çãªããã¹ãã®æ«å°Ÿã
ECMA C# draft specification