কনটেক্সারপ ইনলাইন অন্তর্ভুক্ত করে?


105

নিম্নলিখিত ইনলাইনড ফাংশনটি বিবেচনা করুন:

// Inline specifier version
#include<iostream>
#include<cstdlib>

inline int f(const int x);

inline int f(const int x)
{
    return 2*x;
}

int main(int argc, char* argv[])
{
    return f(std::atoi(argv[1]));
}

এবং কনস্টেক্সপ্র সমতুল্য সংস্করণ:

// Constexpr specifier version
#include<iostream>
#include<cstdlib>

constexpr int f(const int x);

constexpr int f(const int x)
{
    return 2*x;
}

int main(int argc, char* argv[])
{
    return f(std::atoi(argv[1]));
}

আমার প্রশ্নটি: constexprস্পেসিফায়ার স্পষ্টকারীটিকে কি inlineএই অর্থে বোঝায় যে যদি কোনও constexprফাংশনে একটি অ-ধ্রুবক যুক্তি পাঠানো হয় তবে সংকলকটি ফাংশনটিতে এমন চেষ্টা করবে inlineযে inlineস্পেসিফায়ারটিকে তার ঘোষণায় রাখা হয়েছিল?

সি ++ 11 মান কি গ্যারান্টি দেয়?


5
'[উইল] সংকলক ফাংশনটি ইনলাইন করার চেষ্টা করবে' inlineনির্দিষ্টকারী যা করে তা নয়। (অথবা হতে পারে আমি আপনার বাক্যটিকে ভুল বুঝেছি))
লুস ড্যানটন

5
inlineসুনির্দিষ্টভাবে উল্লেখ করা আর সাথে কিছু হয়েছে ইনলাইনিং
কে-ballo

2
প্রশ্নটি inlineসরাসরি ইনলাইনিংয়ের সাথে সম্পর্কিত যে ভুল অনুমানের দিকে যায়। সুতরাং না, constexprস্পেসিফায়ার inlineসেই অর্থে স্পেসিফারকে বোঝায় না , কারণ সেই অর্থে বিদ্যমান নেই।
খ্রিস্টান রাউ

উত্তর:


139

হ্যাঁ ([dcl.constexpr], সি ++ 11 স্ট্যান্ডার্ডে .17.1.5 / 2): "কনটেক্সটপ্রিফ ফাংশন এবং কনটেক্সটপ্রাপ্ত নির্মাতারা সুস্পষ্টভাবে ইনলাইন (7.1.2)।"

তবে দ্রষ্টব্য, যে কোনও সংকলক কোনও ফাংশন ইনলাইন প্রসারিত করতে পারে কিনা তার উপরে inlineস্পেসিফায়ারটির সত্যই খুব কম (যদি থাকে) প্রভাব রয়েছে। এটি তবে একটি সংজ্ঞা নিয়মকে প্রভাবিত করে এবং সেই দৃষ্টিকোণ থেকে সংকলকটিকে একটি constexprফাংশন হিসাবে কোনও inlineফাংশনের জন্য একই নিয়ম অনুসরণ করতে হবে।

আমিও নির্বিশেষে যে যোগ করা উচিত constexprimplying inlineজন্য নিয়ম constexprসি ++ 11 ফাংশন তাদের প্রয়োজনীয় সহজ যথেষ্ট হবে যে তারা প্রায়ই ইনলাইন সম্প্রসারণ (প্রাথমিক ব্যতিক্রম ঐ যে রিকার্সিভ হয় হচ্ছে) জন্য ভাল প্রার্থী ছিলেন। তারপরেও, বিধিগুলি ক্রমান্বয়ে আলগা হয়ে গেছে, সুতরাং constexprএটি আরও বৃহত্তর, আরও জটিল ক্রিয়াকলাপগুলিতে প্রয়োগ করা যেতে পারে।


সংকলনের সময় ধ্রুবক মত প্রকাশের মূল্যায়ন করা হয়েছে এই ধারণাটি প্রদত্ত যে, আমি মনে করি constexprফাংশনগুলির বেশিরভাগ ব্যবহারের ফলে কোনও কোড উত্পন্ন হবে না ...
কেরেক এসবি

11
constexprসংকলনের সময় কেরেকএসবি ফাংশনগুলি সম্ভাব্যভাবে মূল্যায়ন করা হয়। তবে সি ++ 14 স্ট্যান্ডার্ডটি এমনভাবে আবদ্ধ থাকে যা খুব সম্ভবত রানটাইমের সময় ডাকা হবে। উদাহরণস্বরূপ:std::array<T,N>::at
এপোনামস

@ নামবিহীন হ্যাঁ তবে কেবল সর্বাধিক হ্রাস প্রাপ্ত ফর্মটি যদিও অপকড হিসাবে থাকবে। উদাহরণস্বরূপ: সীমাবদ্ধ চেকগুলি নির্মানের সময় মূল্যায়ন করা হবে, যেহেতু তাদের কোড পাথ কনস্টেন্ট। তবে প্রত্যাবর্তিত মান হবে * (ডেটা + অফসেট)
v.oddou

16

constexprinlineঅ স্থিতিশীল ভেরিয়েবলগুলির জন্য বোঝায় না (সি ++ 17 ইনলাইন ভেরিয়েবল)

ফাংশনগুলির জন্য constexprবোঝানো হলেও inline, এটি সি ++ 17 ইনলাইন ভেরিয়েবল বিবেচনা করে স্থিতিশীল ভেরিয়েবলগুলির জন্য সেটির প্রভাব ফেলবে না।

উদাহরণস্বরূপ, আপনি পোস্ট করা সর্বনিম্ন উদাহরণটি গ্রহণ করলে: ইনলাইন ভেরিয়েবলগুলি কীভাবে কাজ করবে? এবং মুছে ফেলুন inline, ঠিক রেখে constexpr, তারপরে ভেরিয়েবলটি একাধিক ঠিকানা পায়, যা মূল বিষয়টি ইনলাইন ভেরিয়েবলগুলি এড়ানো যায়।

constexpr স্ট্যাটিক ভেরিয়েবলগুলি অবশ্য স্পষ্টতই স্থির।

ন্যূনতম উদাহরণ যা ফাংশনগুলির জন্য constexprবোঝায়inline

যেমনটি উল্লেখ করা হয়েছে: https://stackoverflow.com/a/14391320/895245 এর মূল প্রভাবটি inlineইনলাইন করা নয় তবে কোনও ফাংশনের একাধিক সংজ্ঞা, স্ট্যান্ডার্ড কোটকে মঞ্জুরি দেওয়া: সি ++ শিরোলেখ ফাইলটি কীভাবে বাস্তবায়ন অন্তর্ভুক্ত করতে পারে?

নিম্নলিখিত উদাহরণের সাথে খেলে আমরা তা পর্যবেক্ষণ করতে পারি:

main.cpp

#include <cassert>

#include "notmain.hpp"

int main() {
    assert(shared_func() == notmain_func());
}

notmain.hpp

#ifndef NOTMAIN_HPP
#define NOTMAIN_HPP

inline int shared_func() { return 42; }
int notmain_func();

#endif

notmain.cpp

#include "notmain.hpp"

int notmain_func() {
    return shared_func();
}

সংকলন এবং চালান:

g++ -c -ggdb3  -O0 -Wall -Wextra -std=c++11 -pedantic-errors  -o 'notmain.o' 'notmain.cpp' 
g++ -c -ggdb3  -O0 -Wall -Wextra -std=c++11 -pedantic-errors  -o 'main.o' 'main.cpp' 
g++ -ggdb3  -O0 -Wall -Wextra -std=c++11 -pedantic-errors  -o 'main.out' notmain.o main.o
./main.out

যদি আমরা এর inlineথেকে সরিয়ে shared_funcফেলি তবে লিঙ্কটি এতে ব্যর্থ হবে:

multiple definition of `shared_func()'

কারণ শিরোনাম একাধিক .cppফাইলের মধ্যে অন্তর্ভুক্ত হয়ে যায় ।

কিন্তু আমরা যদি প্রতিস্থাপন inlineসঙ্গে constexpr, তারপর এটি আবার কাজ করে, কারণ constexprএছাড়াও বোঝা inline

ELF অবজেক্ট ফাইলগুলিতে প্রতীকগুলি দুর্বল হিসাবে চিহ্নিত করে জিসিসি প্রয়োগ করে: একটি সি ++ শিরোলেখ ফাইলটি কীভাবে বাস্তবায়নকে অন্তর্ভুক্ত করতে পারে?

জিসিসি 8.3.0 এ পরীক্ষিত।


3
বিটিডাব্লু, ঘোষিত স্ট্যাটিক ক্লাসের সদস্য ভেরিয়েবল constexprএখনও ইনলাইন। cppreferences.com : একটি স্ট্যাটিক সদস্য ভেরিয়েবল (তবে একটি নেমস্পেস-স্কোপ ভেরিয়েবল নয়) ঘোষিতconstexpr সুস্পষ্টভাবে একটি ইনলাইন ভেরিয়েবল।
অ্যান্টন_আরহ

@ অ্যান্ট_আর ধন্যবাদ, আমি সেই নিয়মটি দেখিনি, উত্তরটি আপডেট করুন।
সিরো সান্তিলি 郝海东 冠状 病 六四 事件

এটি ওপেন -std.org/JTC1/SC22/WG21/docs/papers/2016/p0386r0.pdf যা বলে তা নয় । এটি বলেছে কনটেক্সপ্রপ ভেরিয়েবলের জন্য ইনলাইনকে বোঝায়। শ্রেণীর ক্ষেত্রের নেমস্পেসের স্কোপের মধ্যে কোনও পার্থক্যের উল্লেখ নেই।
v.oddou
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.