ন্যূনতম চলমান উদাহরণ
এই দুর্দান্ত সি ++ 17 বৈশিষ্ট্যটি আমাদের এতে অনুমতি দেয়:
- প্রতিটি ধ্রুবক জন্য সুবিধামত কেবল একটি একক মেমরি ঠিকানা ব্যবহার করুন
- এটি একটি হিসাবে সংরক্ষণ করুন
constexpr
: কীভাবে বহিরাগতকে ঘোষণা করবেন?
- এটি একটি শিরোলেখ থেকে একক লাইনে করুন
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
গিটহাব উজানের দিকে ।
আরও দেখুন: ইনলাইন ভেরিয়েবলগুলি কীভাবে কাজ করে?
ইনলাইন ভেরিয়েবলগুলিতে সি ++ স্ট্যান্ডার্ড
সি ++ স্ট্যান্ডার্ড গ্যারান্টি দেয় যে ঠিকানাগুলি একই হবে। সি ++ 17 এন 4659 স্ট্যান্ডার্ড খসড়া
10.1.6 "ইনলাইন স্পেসিফায়ার":
External বাহ্যিক সংযোগের সাথে একটি ইনলাইন ফাংশন বা ভেরিয়েবলের সমস্ত অনুবাদ ইউনিটে একই ঠিকানা থাকবে।
cppreferences https://en.cppreferences.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
:
"u" প্রতীকটি একটি অনন্য বৈশ্বিক প্রতীক। এটি ELF প্রতীক বাইন্ডিংয়ের মানক সেটটিতে একটি GNU এক্সটেনশন। এই জাতীয় প্রতীকের জন্য ডায়নামিক লিঙ্কার নিশ্চিত করবে যে পুরো প্রক্রিয়াতে এই নাম এবং ব্যবহারের টাইপ সহ কেবল একটি প্রতীক রয়েছে।
সুতরাং আমরা দেখতে পাচ্ছি যে এর জন্য একটি ডেডিকেটেড ইএলএফ এক্সটেনশন রয়েছে।
প্রাক-সি ++ 17: extern const
সি ++ 17 এর আগে এবং সি-তে আমরা একটির সাথে খুব অনুরূপ প্রভাব অর্জন করতে পারি 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.cppreferences.com/w/cpp/language/static "কনস্ট্যান্ট স্ট্যাটিক সদস্য" এবং কনটেক্সট্রিক স্ট্যাটিক ডেটা সংজ্ঞায়িত করা সদস্যদের
সি
সিতে পরিস্থিতি সি ++ প্রাক সি ++ 17 এর মতোই, আমি এখানে একটি উদাহরণ আপলোড করেছি: "স্ট্যাটিক" সি এর অর্থ কী?
মাত্র তফাত হল যে সি ++ হয় const
বোঝা static
globals জন্য, কিন্তু এটা সি না: বনাম `const`` স্ট্যাটিক const` এর সি ++ শব্দার্থবিদ্যা
এটি সম্পূর্ণরূপে ইনলাইন করার কোনও উপায়?
টোডো: কোনও স্মৃতি ব্যবহার না করে ভেরিয়েবলকে সম্পূর্ণরূপে ইনলাইন করার কোনও উপায় আছে কি?
প্রিপ্রোসেসর কী করে তা অনেকটা পছন্দ করে।
এটির কোনওরকম প্রয়োজন হবে:
- পরিবর্তনশীলের ঠিকানা নেওয়া হয়েছে কিনা তা নিষিদ্ধ বা সনাক্তকরণ
- ELF অবজেক্ট ফাইলগুলিতে সেই তথ্য যুক্ত করুন, এবং LTO এটির সর্বোত্তম করুন
সম্পর্কিত:
উবুন্টু 18.10, জিসিসি 8.2.0 এ পরীক্ষিত।
const
।