न्यूनतम रननीय उदाहरण
यह भयानक C ++ 17 फीचर हमें इसकी अनुमति देता है:
main.cpp
#include <cassert>
#include "notmain.hpp"
int main() {
// Both files see the same memory address.
assert(¬main_i == notmain_func());
assert(notmain_i == 42);
}
notmain.hpp
#ifndef NOTMAIN_HPP
#define NOTMAIN_HPP
inline constexpr int notmain_i = 42;
const int* notmain_func();
#endif
notmain.cpp
#include "notmain.hpp"
const int* notmain_func() {
return ¬main_i;
}
संकलित करें और चलाएं:
g++ -c -o notmain.o -std=c++17 -Wall -Wextra -pedantic notmain.cpp
g++ -c -o main.o -std=c++17 -Wall -Wextra -pedantic main.cpp
g++ -o main -std=c++17 -Wall -Wextra -pedantic main.o notmain.o
./main
गिटहब ऊपर ।
यह भी देखें: इनलाइन चर कैसे काम करते हैं?
इनलाइन चरों पर C ++ मानक
C ++ मानक गारंटी देता है कि पते समान होंगे। C ++ 17 N4659 मानक मसौदा
10.1.6 "इनलाइन विनिर्देशक":
6 बाहरी लिंकेज के साथ एक इनलाइन फ़ंक्शन या चर सभी अनुवाद इकाइयों में एक ही पता होगा।
cppreference https://en.cppreference.com/w/cpp/language/inline बताता है कि अगर static
नहीं दिया गया है, तो इसमें बाहरी लिंकेज है।
जीसीसी इनलाइन चर कार्यान्वयन
हम यह देख सकते हैं कि इसे किस प्रकार लागू किया जाता है:
nm main.o notmain.o
जिसमें है:
main.o:
U _GLOBAL_OFFSET_TABLE_
U _Z12notmain_funcv
0000000000000028 r _ZZ4mainE19__PRETTY_FUNCTION__
U __assert_fail
0000000000000000 T main
0000000000000000 u notmain_i
notmain.o:
0000000000000000 T _Z12notmain_funcv
0000000000000000 u notmain_i
और के man nm
बारे में कहते हैं u
:
"यू" प्रतीक एक अद्वितीय वैश्विक प्रतीक है। यह ईएलएफ प्रतीक बाइंडिंग के मानक सेट के लिए एक जीएनयू विस्तार है। इस तरह के प्रतीक के लिए डायनेमिक लिंकर यह सुनिश्चित करेगा कि पूरी प्रक्रिया में इस नाम और उपयोग के प्रकार के साथ सिर्फ एक प्रतीक है।
इसलिए हम देखते हैं कि इसके लिए एक समर्पित ईएलएफ एक्सटेंशन है।
प्री-सी ++ 17: extern const
C ++ 17 से पहले, और C में, हम एक के साथ एक बहुत ही समान प्रभाव प्राप्त कर सकते हैं extern const
, जिससे एकल मेमोरी लोकेशन का उपयोग किया जा सकेगा।
नीचे की ओर inline
हैं:
constexpr
इस तकनीक के साथ वैरिएबल बनाना संभव नहीं है , केवल यह inline
अनुमति देता है: कॉन्स्ट्रेक्ट एक्सटर्नल कैसे घोषित करें?
- यह कम सुरुचिपूर्ण है क्योंकि आपको हेडर और सीपीपी फ़ाइल में अलग से चर को घोषित करना और परिभाषित करना है
main.cpp
#include <cassert>
#include "notmain.hpp"
int main() {
// Both files see the same memory address.
assert(¬main_i == notmain_func());
assert(notmain_i == 42);
}
notmain.cpp
#include "notmain.hpp"
const int notmain_i = 42;
const int* notmain_func() {
return ¬main_i;
}
notmain.hpp
#ifndef NOTMAIN_HPP
#define NOTMAIN_HPP
extern const int notmain_i;
const int* notmain_func();
#endif
गिटहब ऊपर ।
प्री-सी ++ 17 हेडर केवल विकल्प
ये extern
समाधान के रूप में अच्छे नहीं हैं, लेकिन वे काम करते हैं और केवल एक ही मेमोरी स्थान लेते हैं:
एक constexpr
फ़ंक्शन, क्योंकि constexpr
इसका तात्पर्य inline
inline
प्रत्येक अनुवाद इकाई पर दिखने वाली परिभाषा (बलों) से है और अनुमति देता है :
constexpr int shared_inline_constexpr() { return 42; }
और मैं शर्त लगाता हूं कि किसी भी सभ्य संकलक कॉल को इनलाइन करेगा।
आप निम्न के रूप में const
या constexpr
स्थिर पूर्णांक चर का भी उपयोग कर सकते हैं :
#include <iostream>
struct MyClass {
static constexpr int i = 42;
};
int main() {
std::cout << MyClass::i << std::endl;
// undefined reference to `MyClass::i'
//std::cout << &MyClass::i << std::endl;
}
लेकिन आप इसका पता लेने जैसी चीजें नहीं कर सकते हैं, या फिर यह ओड-यूज़ हो जाता है, यह भी देखें: https://en.cppreference.com/w/cpp/language/static "लगातार स्थैतिक सदस्य" और स्थिर स्थैतिक डेटा को परिभाषित करना सदस्यों
सी
C में स्थिति C ++ पूर्व C ++ 17 जैसी ही है, मैंने इस पर एक उदाहरण अपलोड किया है: C में "स्थिर" का क्या अर्थ है?
फर्क सिर्फ इतना है कि C ++, है const
तात्पर्य static
वैश्विक के लिए, लेकिन यह सी में नहीं करता है: बनाम `` const` स्थिर const` की सी ++ अर्थ विज्ञान
इसे पूरी तरह से इनलाइन करने का कोई तरीका?
TODO: क्या किसी भी मेमोरी का उपयोग किए बिना, चर को पूरी तरह से इनलाइन करने का कोई तरीका है?
प्रीप्रोसेसर क्या पसंद करता है।
इसके लिए किसी तरह की आवश्यकता होगी:
- यदि चर का पता लिया जाए तो मना करना या पता लगाना
- उस जानकारी को ELF ऑब्जेक्ट फ़ाइलों में जोड़ें, और LTO को इसे ऑप्टिमाइज़ करने दें
सम्बंधित:
उबंटू 18.10, जीसीसी 8.2.0 में परीक्षण किया गया।
const
।