কনস্টের সাথে ভেরিয়েবল আরম্ভ করার চেষ্টা করার সময় ত্রুটি "আরম্ভকারী উপাদান ধ্রুবক নয়"


186

আমি নিম্নলিখিত প্রোগ্রামটির 6 লাইনে (my_foo- কে foo_init প্রারম্ভিক) একটি ত্রুটি পেয়েছি এবং কেন নিশ্চিত তা আমি নিশ্চিত নই।

typedef struct foo_t {
    int a, b, c;
} foo_t;

const foo_t foo_init = { 1, 2, 3 };
foo_t my_foo = foo_init;

int main()
{
    return 0;
}

মনে রাখবেন এটি আমি কাজ করছি এমন একটি বৃহত, বহু-ফাইল প্রকল্পের একটি সরলীকৃত সংস্করণ। লক্ষ্যটি ছিল অবজেক্ট ফাইলে একটি একক ধ্রুবক থাকা, একাধিক ফাইল কোনও রাষ্ট্র কাঠামো সূচনা করতে ব্যবহার করতে পারে। যেহেতু এটি সীমিত সংস্থান সহ এম্বেডড লক্ষ্য এবং কাঠামোটি এত ছোট নয়, আমি উত্সটির একাধিক অনুলিপি চাই না। আমি ব্যবহার না করা পছন্দ করব:

#define foo_init { 1, 2, 3 }

আমি পোর্টেবল কোডও লেখার চেষ্টা করছি, সুতরাং আমার কাছে এমন একটি সমাধান দরকার যা বৈধ C89 বা C99।

এটি কি কোনও অবজেক্ট ফাইলে ওআরজিগুলির সাথে সম্পর্কযুক্ত? সেই আরম্ভকৃত ভেরিয়েবলগুলি একটি ওআরজিতে যায় এবং দ্বিতীয় ওআরজির বিষয়বস্তু অনুলিপি করে আরম্ভ করা হয়?

হয়তো আমার কেবল আমার কৌশলটি পরিবর্তন করতে হবে এবং প্রারম্ভকালে সমস্ত অনুলিপি শুরু করার একটি প্রাথমিক কাজ করব। সেখানে অন্য ধারণা না থাকলে?

উত্তর:


269

সি ভাষায়, স্থির স্টোরেজ সময়কাল সহ অবজেক্টগুলিকে ধ্রুবক অভিব্যক্তি দিয়ে শুরু করতে হবে সাথে বা সহ সামগ্রিক প্রাথমিকের সাথে ।

"বৃহত্তর" অবজেক্টটি সিতে কখনই একটি ধ্রুবক প্রকাশ হয় না, এমনকি যদি বস্তু হিসাবে ঘোষিত হয় const

তাছাড়া, সি ভাষায়, শব্দটি "ধ্রুবক" বোঝায় আক্ষরিক ধ্রুবক (যেমন 1, 'a', 0xFFইত্যাদি), enum সদস্য এবং যেমন অপারেটরদের ফলাফল sizeof। কনস্ট-কোয়ালিফাইড অবজেক্টস (যে কোনও ধরণের) সি ভাষার পরিভাষায় স্থির নয় । এগুলি স্ট্যাটিক স্টোরেজ সময়কাল সহ অবজেক্টের আরম্ভকারীগুলিতে ব্যবহার করা যাবে না, তাদের প্রকার নির্বিশেষে।

উদাহরণস্বরূপ, এই হল না একটি ধ্রুবক

const int N = 5; /* `N` is not a constant in C */

উপরে NC ++ একটি ধ্রুবক হতে পারে, কিন্তু এটা, সি সুতরাং একটি ধ্রুবক নয় যদি আপনি করছেন চেষ্টা

static int j = N; /* ERROR */

আপনি একই ত্রুটিটি পাবেন: অ-ধ্রুবক সহ একটি স্ট্যাটিক অবজেক্টটি আরম্ভ করার চেষ্টা।

এই কারণেই, সি ভাষায়, আমরা মূলত #defineনামযুক্ত ধ্রুবকগুলি ঘোষণার জন্য ব্যবহার করি , এবং #defineনামকরণকৃত সমষ্টিগত আরম্ভকারী তৈরি করতেও অবলম্বন করি ।


2
চমৎকার ব্যাখ্যার জন্য +5, তবে আশ্চর্যরূপে এই প্রোগ্রামটি আদর্শের উপর জরিমানা সংকলন করেছে: আদর্শ one.com/lx4Xed । এটি কি সংকলক বাগ বা সংকলক এক্সটেনশন? ধন্যবাদ
ধ্বংসকারী

2
@ মিঃ: আমি জানি না যে সংকলক বিকল্পগুলির সংমিশ্রণগুলি আদর্শের ফণার নীচে কী ব্যবহার করে তবে তাদের ফলাফল প্রায়শই বিবরণের বাইরে we আমি এই কোডটি কলিরুতে সংকলনের চেষ্টা করেছি ( coliru.stacked-crooked.com/a/daae3ce4035f5c8b ) এবং আমি সি ভাষার উপভাষার সেটিংটি ব্যবহার না করেই এর জন্য প্রত্যাশিত ত্রুটি পেয়েছি। আমি জি সি সি এর সম্প্রসারণ হিসাবে জিসিসির ওয়েবসাইটে তালিকাভুক্ত এর মতো কিছু দেখতে পাচ্ছি না। অন্য কথায়, এটি কীভাবে এবং কেন আদর্শে সংকলিত হয় সে সম্পর্কে আমার কোনও ধারণা নেই। এমনকি এটি ভাষা বর্ধন হিসাবে সংকলন করা সত্ত্বেও এটি সি
তে

15
enum { N = 5 };অবলম্বন না করেই ধ্রুবকগুলি ঘোষণা করার একটি স্বল্প-প্রশংসিত উপায় #define
এমএম

2
@ প্রবাসীমিট "আইডিয়োন" কম্পাইলারটি নির্ধারণ করে যে ডায়াগনস্টিক বার্তাগুলি কেবল প্রদর্শন করে না, তাই কোডটি সঠিক কিনা তা নির্ধারণের জন্য এটি খুব ভাল সাইট নয়।
এমএম

1
আমি আকর্ষণীয় কিছু খুঁজে পেয়েছি। যদি পিটিআর কোনও ফাংশনের অভ্যন্তরে সংজ্ঞায়িত হয় static int* ptr = malloc(sizeof(int)*5);তবে এটি ত্রুটি: তবে এটি ত্রুটি নয় static int* ptr; ptr = malloc(sizeof(int)*5);: ডি
অ্যাডারচক্স

74

এটি ভাষার সীমাবদ্ধতা। বিভাগে 6.7.8 / 4:

স্ট্যাটিক স্টোরেজ সময়কালের জন্য কোনও অবজেক্টের জন্য ইনিশিয়ালাইজারের সমস্ত এক্সপ্রেশন হ'ল স্থির এক্সপ্রেশন বা স্ট্রিং লিটারাল।

Section. section বিভাগে, অনুমানটি একটি ধ্রুবক অভিব্যক্তি বিবেচনা করতে হবে কি সংজ্ঞায়িত করে। কোনটি এটি কোথায় উল্লেখ করে না যে একটি কনস্ট কনক চলক অবশ্যই একটি ধ্রুবক অভিব্যক্তি হিসাবে বিবেচিত হবে। কোনও সংকলকের পক্ষে এটি ( 6.6/10 - An implementation may accept other forms of constant expressions) প্রসারিত করা আইনী তবে এটি বহনযোগ্যতা সীমাবদ্ধ করে।

যদি আপনি এটি পরিবর্তন করতে পারেন my_fooযাতে এটিতে স্ট্যাটিক স্টোরেজ না থাকে তবে আপনি ঠিক থাকবেন:

int main()
{
    foo_t my_foo = foo_init;
    return 0;
}

আমি পছন্দ করি যে আপনি অনুমিতি উদ্ধৃত করেছেন, তবে এটি আমাদের কী করতে হবে বা জিনিসগুলি কেন সেভাবে হয় তা বুঝতে সহায়তা করে না।
ইভান ক্যারল

1
এটি জিসিসি 8.1 (এবং পরে) এই উত্তরে বর্ণিত হিসাবে কিছু এক্সটেনশন কার্যকর করেছে বলে মনে হয়; এটা গ্রহণ করে static const int x = 3; static int y = x;
এরিক পোস্টপিসিল

5

কেবল তুলনা এবং বিপরীতে উদাহরণের জন্য কোডটি http://www.geeksforgeeks.org/g-fact-80/ / এর থেকে কোডটি জিসিসিতে ব্যর্থ হয় এবং জি ++ / এ পাস করে

#include<stdio.h>
int initializer(void)
{
    return 50;
}

int main()
{
    int j;
    for (j=0;j<10;j++)
    {
        static int i = initializer();
        /*The variable i is only initialized to one*/
        printf(" value of i = %d ", i);
        i++;
    }
    return 0;
}

2

এটি কিছুটা পুরানো, তবে আমি একই ধরণের সমস্যায় পড়েছি। আপনি যদি কোনও পয়েন্টার ব্যবহার করেন তবে আপনি এটি করতে পারেন:

#include <stdio.h>
typedef struct foo_t  {
    int a; int b; int c;
} foo_t;
static const foo_t s_FooInit = { .a=1, .b=2, .c=3 };
// or a pointer
static const foo_t *const s_pFooInit = (&(const foo_t){ .a=2, .b=4, .c=6 });
int main (int argc, char **argv) {
    const foo_t *const f1 = &s_FooInit;
    const foo_t *const f2 = s_pFooInit;
    printf("Foo1 = %d, %d, %d\n", f1->a, f1->b, f1->c);
    printf("Foo2 = %d, %d, %d\n", f2->a, f2->b, f2->c);
    return 0;
}

5
স্থিতিশীল স্টোরেজ সময়কাল সহ আমি ভেরিয়েবলটি দেখতে পাচ্ছি না যা এখানে অ-ধ্রুবক দ্বারা আরম্ভ করা হয়েছে।
বিদায় SE

0

gcc 7.4.0 নীচের মত কোডগুলি সংকলন করতে পারে না:

#include <stdio.h>
const char * const str1 = "str1";
const char * str2 = str1;
int main() {
    printf("%s - %s\n", str1, str2);
    return 0;
}

constchar.c: 3: 21: ত্রুটি: ইনিশিয়ালাইজার উপাদান ধ্রুব কনস্ট চার্জ নয় * str2 = str1;

আসলে, "কনস্ট চর" * স্ট্রিং সংকলন-সময় ধ্রুবক নয়, সুতরাং এটি আরম্ভকারী হতে পারে না। তবে "কনস্ট চর * কনস্ট" স্ট্রিং একটি সংকলন-সময় ধ্রুবক, এটি একটি আরম্ভকারী হতে সক্ষম হওয়া উচিত। আমি মনে করি এটি ক্লাংয়ের একটি ছোট্ট অপূর্ণতা।

একটি ফাংশন নাম অবশ্যই একটি সংকলন-সময় ধ্রুবক। সুতরাং এই কোডটি কাজ করে:

void func(void)
{
    printf("func\n");
}
typedef void (*func_type)(void);
func_type f = func;
int main() {
    f();
    return 0;
}

আপনি যে কোডটি পোস্ট ইন, str1একটি নয় অভিব্যক্তি প্রতি 6.7.9 সূচনা অনুচ্ছেদ 4 : "। একটি বস্তু আছে যা স্ট্যাটিক বা থ্রেড স্টোরেজ সময়কাল ধ্রুবক এক্সপ্রেশন বা স্ট্রিং লিটারেল হইবে একটি সূচনাকারী এর মধ্যে এক্সপ্রেশন"
অ্যান্ড্রু হেনেল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.