#keywords C++ C/C++ ì— ìžˆëŠ” 키워드 중ì—ì„œ 가장 사용 빈ë„ê°€ ë‚®ì€ í‚¤ì›Œë“œë¼ê³ ì•Œë ¤ì ¸ 있다. {{{+1 ì˜ë¯¸ }}} `volatile` 키워드는 해당 변수가 ì–¸ì œë“ ì§€ 예기치 않게 변경ë 수 있ìŒì„ 컴파ì¼ëŸ¬ì— 알리는 ì—í• ì„ í•œë‹¤. ë”°ë¼ì„œ 컴파ì¼ëŸ¬ëŠ” ë³€ìˆ˜ì— ìµœì 화를 수행하지 않는다. 즉, 컴파ì¼ëŸ¬ê°€ ê°’ì„ ì˜ˆì¸¡í•˜ê±°ë‚˜ ìºì‹±í•˜ëŠ” ê²ƒì„ ë°©ì§€í•˜ê¸° ë•Œë¬¸ì— ë ˆì§€ìŠ¤í„°ë¥¼ 사용하지 ì•Šê³ ë§¤ë²ˆ 메모리ì—ì„œ ì½ëŠ”다 `volatile` 키워드를 ì´í•´í•˜ë ¤ë©´ C/C++ 컴파ì¼ëŸ¬ê°€ ë³€ìˆ˜ì— ëŒ€í•´ 어떻게 최ì 화를 하는지 알아야 한다. {{{+1 C/C++ì˜ ìµœì í™” }}} ì˜ë¦¬í•œ 컴파ì¼ëŸ¬ë¼ë©´ 코드ì—ì„œ ê°™ì€ ì£¼ì†Œì˜ ë©”ëª¨ë¦¬ë¥¼ 여러 번 ì½ê³ , ë§ˆì§€ë§‰ì— í•œë²ˆ 쓰는 걸 발견하면 ì†ë„를 í–¥ìƒ ì‹œí‚¤ê¸° 위해 최종ì 으로 불필요한 ì½ê¸°ë¥¼ ì œê±°í•˜ê³ ë§ˆì§€ë§‰ì— ì“°ê¸°ë§Œ ìˆ˜í–‰í• ê²ƒì´ë‹¤. ì¼ë°˜ì ì¸ ì½”ë“œë¼ë©´ ì´ëŸ° 최ì 화를 통해 수행 ì†ë„ ë©´ì—ì„œ ì´ë“ì„ ë³´ê²Œ ëœë‹¤. 하지만 ìž„ë² ë””ë“œ 장비처럼 메모리 ì£¼ì†Œì— ì—°ê²°ëœ í•˜ë“œì›¨ì–´ ê°’ì„ ì½ì–´ì˜¨ë‹¤ë©´ ì´ì•¼ê¸°ê°€ 달ë¼ì§„다(`Memory-mapped I/O`). ì–¸ì œë“ ì§€ ê°’ì´ ë³€ê²½ë 수 있기 ë•Œë¬¸ì— ì£¼ì†Œê°€ 같다는 ì´ìœ 만으로 메모리 ì½ê¸°ë¥¼ 예측하거나 ìºì‹±í•˜ì—¬ 넘기면 안ëœë‹¤. ì´ëŸ° 경우 ìœ ìš©í•˜ê²Œ 사용ë 수 있는 키워드가 `volatile`ì´ë‹¤. ë©€í‹°ìŠ¤ë ˆë“œ í™˜ê²½ë„ ë§ˆì°¬ê°€ì§€ë¡œ 수행 ë„중 다른 ìŠ¤ë ˆë“œê°€ ì „ì— ë³€ìˆ˜ ê°’ì„ ìž„ì˜ë¡œ ë³€ê²½í• ìˆ˜ 있다. 하지만 컴파ì¼ëŸ¬ê°€ 코드를 ìƒì„±í• 때는 다른 ìŠ¤ë ˆë“œì˜ ì¡´ìž¬ 여부를 모르므로 변수 ê°’ì„ ë§¤ë²ˆ 새로 ì½ì–´ì˜¤ì§€ 않는다. ë”°ë¼ì„œ 여러 ìŠ¤ë ˆë“œê°€ ê³µìœ í•˜ëŠ” ì „ì— ë³€ìˆ˜ë¼ë©´ `volatile`ë¡œ ì„ ì–¸í•´ 주거나 명시ì 으로 ë½ì„ 잡아야 한다. {{{+1 volatileì´ ì‚¬ìš©ë˜ëŠ” 3가지 ìƒí™© }}} 1. 하드웨어 ë ˆì§€ìŠ¤í„°ì™€ ìƒí˜¸ 작용하는 경우: íŠ¹ì • 하드웨어 ë ˆì§€ìŠ¤í„°ì— ê°’ì„ ì½ê³ 쓰는 ë° ì‚¬ìš©ë˜ëŠ” 변수는 예기치 않게 변경ë 수 있다. 2. ë©€í‹°ìŠ¤ë ˆë“œ 환경ì—ì„œ ê³µìœ ë˜ëŠ” 변수: 여러 ìŠ¤ë ˆë“œê°€ ë™ì‹œì— ì ‘ê·¼í• ìˆ˜ 있는 변수는 ì–¸ì œë“ ì§€ 다른 ìŠ¤ë ˆë“œì— ì˜í•´ 변경ë 수 있다. 3. ì¸í„°ëŸ½íŠ¸ 서비스 루틴: ì¸í„°ëŸ½íŠ¸ê°€ ë°œìƒí•˜ë©´ 실행 ì¤‘ì¸ ì½”ë“œê°€ 중단ë˜ê³ ì¸í„°ëŸ½íŠ¸ 서비스 ë£¨í‹´ì´ ì‹¤í–‰ëœë‹¤. ì´ ê²½ìš° ì¸í„°ëŸ½íŠ¸ 서비스 루틴ì—ì„œ 사용ë˜ëŠ” 변수는 예기치 않게 변경ë 수 있으므로 `volatile`ë¡œ ì„ ì–¸í•´ì•¼ 한다. 세 가지 공통ì ì€ í˜„ìž¬ í”„ë¡œê·¸ëž¨ì´ ì‹¤í–‰ ì¤‘ì¸ ì½”ë“œì™€ ìƒê´€ì—†ì´ 외부 ìš”ì¸ì— ì˜í•´ 변수 ê°’ì„ ë³€ê²½í• ìˆ˜ 있다는 ì ì´ë‹¤. ì´ì²˜ëŸ¼ ë ˆì§€ìŠ¤í„°ë¥¼ 재사용하지 ì•Šê³ ë§¤ë²ˆ 메모리를 참조하는 ê²ƒì„ ê°€ì‹œì„±(visibility)ì´ ë³´ìž¥ëœë‹¤ê³ ë§í•œë‹¤. {{{+1 ì›ìžì„± }}} 그러나 주ì˜í• ì ì€ `volatile` 키워드가 ê³µìœ ë³€ìˆ˜ì— ëŒ€í•œ ë™ê¸°í™”를 ì œê³µí•˜ì§€ 않는다. 즉, ë°ì´í„° ê²½ìŸ ì¡°ê±´ì´ë‚˜ ì›ìžì„±ì„ 보장하지 않는다. ì´ëŸ¬í•œ ë™ê¸°í™” ë¬¸ì œë¥¼ 해결하기 위해서는 C++11 ì´í›„ì˜ í‘œì¤€ì—ì„œ ë„ìž…ëœ `std::atomic` 타입ì´ë‚˜ 뮤í…스와 ê°™ì€ ë™ê¸°í™” ë©”ì»¤ë‹ˆì¦˜ì„ ì‚¬ìš©í•´ì•¼ 한다. {{{+1 재배치Reordering }}} `volatile`ì€ í‘œì¤€ì—ì„œ 키워드와 메모리 모ë¸ì— 대해 명확한 ì •ì˜ë¥¼ 내리지 않았기 ë•Œë¬¸ì— ì»´íŒŒì¼ëŸ¬ë§ˆë‹¤ êµ¬í˜„ì— ì°¨ì´ê°€ 있다. MSVC는 `volatile`ì— ê°€ì‹œì„± ë¿ë§Œ ì•„ë‹ˆë¼ ìž¬ë°°ì¹˜Reordering ë¬¸ì œì— ëŒ€í•œ í•´ê²°ì±…ë„ ì¶”ê°€í•˜ì˜€ë‹¤. 재배치는 컴파ì¼ëŸ¬ê°€ 메모리 ì ‘ê·¼ ì†ë„ í–¥ìƒ, 파ì´í”„ë¼ì¸ 활용 등 최ì í™” 목ì 으로 프로그램 ëª…ë ¹ì˜ ìœ„ì¹˜ë¥¼ 바꾸는 ê²ƒì„ ë§í•˜ëŠ”ë°, 코드 ìƒì— a = 1; b = 1; c = 1;ë¼ê³ ìž‘ì„±í–ˆë‹¤ê³ í•´ì„œ 반드시 abc 순서로 ë©”ëª¨ë¦¬ì— ì“°ì§€ ì•Šì„ ìˆ˜ë„ ìžˆë‹¤ëŠ” ì˜ë¯¸ë‹¤. ìºì‹œ ìƒí™© ë“±ì— ë”°ë¼ ì†ë„ í–¥ìƒì„ ë³¼ 수 있다면 컴파ì¼ëŸ¬ëŠ” a,c를 ë¨¼ì € ì“°ê³ b를 쓰는 순서가 바꿀 수 있는 것ì´ë‹¤. `volatile`ì„ ì‚¬ìš©í•˜ë©´ 컴파ì¼ëŸ¬ê°€ 수행하는 ìž¬ë°°ì¹˜ì— ì œì•½ì„ ì¤€ë‹¤. `volatile`ì€ ë‹¨ì¼ CPU 환경ì—ì„œ 재배치 ë¬¸ì œëŠ” í•´ê²°í•´ 주지만 멀티 CPUì˜ ìž¬ë°°ì¹˜ì— ëŒ€í•´ì„œëŠ” ì™„ì „í•œ ëŒ€ì•ˆì„ ì œê³µí•´ì£¼ì§€ 못한다. ìœ ìš©ì„±ê³¼ 한계를 충분히 ì¸ì§€í•˜ê³ `volatile`ì„ ì‚¬ìš©í•˜ìž. ---- CategoryDocument