اطلاعیه

Collapse
No announcement yet.

__INLINE static void

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    __INLINE static void

    INLINE static void__
    این دستور یعنی چی؟

    #2
    پاسخ : __INLINE static void

    واقعا یعنی چی؟
    من همیشه تو کدهای C میبینم ولی تو برنامه نویسی میکرو static بودن تابع چه معنی ای میده؟
    ولی inline یعنی که تابع بجای فراخوانی شدن کپی میشه تو محل فراخوانی و اینطوری stack رو اشغال نمیکنه ولی فلش رو بیشتر اشغال میکنه.
    بت در بغل و به سجده پیشانی ما کافر زده خنده بر مسلمانی ما
    اسلام به ذات خود ندارد عیبی هر عیب که هست در این مسلمانی ماست

    دیدگاه


      #3
      پاسخ : __INLINE static void

      با سلام
      نوشته اصلی توسط mostafahk
      واقعا یعنی چی؟
      من همیشه تو کدهای C میبینم ولی تو برنامه نویسی میکرو static بودن تابع چه معنی ای میده؟
      نوشته اصلی توسط رضا آقازاده
      مثلا فرض کنین پروژه ما از چند سورس مجزا (که include نشن و جدا گانه کامپایل بشن) تشکیل شده. در این حالت object های هر سورس بعد از کامپایل شدن در فاز لینک بهم وصل میشن تا فایل نهایی رو تولید کنن. در این حالت اگر متغیر عمومی یا تابعی بصورت static معرفی بشه (البته طبق قواعد عمومی زبان C) دیگه به اسم خودش در object نهایی معرفی نمیشه. یعنی نمیشه از object های دیگه شناسایی بشه و نتیجتا قابل صدا کردن هم نیست:


      کد:
      file main.c:
      
      void main(void)
      {
        func1_in_test_c();
        wait_for_response();
      }
      
      
      file test.c
      
      void func1_in_test_c(void)
      {
      }
      
      
      file uart.c
      
      static void wait_for_response(void)
      {
      }
      
      --------
      
      a part of project map file
      
       .text     0x000000a4    0xa main.o
              0x000000a4        main
       .text     0x000000ae    0x2 test.o
              0x000000ae        func1_in_test_c
       .text     0x000000b0    0x0 uart.o
       .text     0x000000b0    0x0 c:/winavr/bin/../lib/gcc/avr/4.3.3/avr5\libgcc.a(_exit.o)
              0x000000b0        . = ALIGN (0x2)
      
      
      --------
      
      compile error
      
      Z:\Projects\test\test\default/../main.c:8: undefined reference to `wait_for_response'



      اگر توجه کنین میبینین که با اینکه تمامی توابع در پروژه موجوده و کامپایلر WinAVR خطا میده که نماد wait_for_response رو نمیشناسه. این بخاطر استفاده از لغت static در هنگام نوشتن تابع هست که به کامپایلر حالی میکنه که object نهایی نباید حاوی اسم این تابع باشه.

      دیدگاه


        #4
        پاسخ : __INLINE static void

        ....
        ضمنا inline قید کردن یک تابع؛ الزامی برای inline شدنش ایجاد نمیکنه بلکه شرایطی داره که باید اون شرایط وجود داشته باشه. مثلا یک تابع recursive (تابعی که خودش خودش رو صدا میکنه) رو نمیشه inline کرد حتی اگر Inline معرفی بشه.

        دیدگاه


          #5
          پاسخ : __INLINE static void

          ممنون از جوابتون امکانش هست یکم ساده تر توضیح بدین که منم متوجه بشم

          دیدگاه


            #6
            پاسخ : __INLINE static void

            خیلی وقتها پیش میاد که بخواییم بنا بر دلایلی یک منطق رو بفرم یک تابع در بیاریم. مثلا وارون یک ماتریس حساب بشه. اما به ازای هر بار فراخوانی یک تابع کلی عملیات جنبی هم باید انجام بشه. و این سرعت اجرای رو کند میکنه. از طرفی حجم نهایی برنامه هم به ما اجازه نمیده که از ماکرو ها استفاده کنیم. و غیر از این ها یک ماکرو محدوده اجرایی جدایی نداره. مثلا یک ماکرو پشته مخصوص خودش رو نداره چون قبل از پردازش نهایی توسط کامپایلر حذف میشه. و اصولا در هنگام کامپایل چیزی ازش باقی نمونده. بنا براین میریم سراغ تابع. اما برای حالتی مثل ماکرو ایجاد کردن میتونیم یک تابع رو inline معرفی کنیم. یعنی به کامپایلر اجازه میدیم در صورتی که صلاح دید این تابع رو در محل صدا زدنش کپی کنه. تازه خیلی وقتها هم برای خوانایی بیشتر مجبوریم از توابع inline استفاده کنیم. اما کامپایلر هم محدودیت های خودش رو داره. مثلا فرض کنین یک تابع مثل این رو:


            int next_index(int n)
            {
            n++;
            if( n == limit )
            n = 0;
            return n;
            }


            براحتی میشه در جایی که استفاده شده insert کرد. چون هم رفتارش برای کامپایلر مشخصه و هم میزان استک مورد استفاده و هم کد ساده ای داره. اما این یکی کد رو در نظر بگیرین:

            int fact(int n)
            {
            if(n == 2)
            return 2;
            return fact(n-1)*n;
            }


            اگر این تابع رو به فرم inline تعریف کنیم کامپایلر قراره چکار کنه؟ کامپایلر به اطلاعات زمان اجرا دسترسی نداره. تا این کد هم صدا زده نشه که نمیشه فهمید مقدار n چقدر هست و چند بار باید این کد در محلی که صدا زده شده (من جمله خود تابع) اضافه بشه. پس اگر من این تابع رو inline معرفی کنم و کامپایلر هم بخواد نمیتونه inline استفاده اش کنه.

            بنا براین من توسط استفاده از لغت inline فقط امکان inline کردن یک تابع رو به کامپایلر پیشنهاد میدم. اون ممکنه بتونه یا نتونه. ممکنه انجام بده یا نده. مثلا فرض کنین یک تابع با حجم کدی در حدود 100 بایت 100 جای متفاوت صدا زده شده. اگر قرار باشه inline بشه چیزی نزدیک 10 کیلو به حجم کد اضافه میکنه. حالا میکرویی داریم با 8 کیلو حافظه فلش. بهینه سازی هم روی حجم هست. اگر بخواد این کد رو inline کنه که دیگه این برنامه بدرد هیچی نمیخوره. چون توی فلش جا نمیشه. ولی ممکنه تشخصی بده شما چون گفتی "بهینه سازی حجمی" پس این لغت inline رو برای این تابع ندیده بگیره بهتره. بخاطر همین بعضی کامپایلر ها جدای از inline دستوری بنام forceinline هم دارن. که به کامپایلر میگه تحت هر شرایطی اگر میتونی inline کنی حتما انجام بده.

            دیدگاه


              #7
              پاسخ : __INLINE static void

              ممنون از پاسختون من کتاب C++قمی را دارم اما چیزی متوجه نشدم مرجع بهتری هست

              دیدگاه


                #8
                پاسخ : __INLINE static void

                جواب من بدرد نخورد یا کتاب بهتری میخوایین؟

                دیدگاه


                  #9
                  پاسخ : __INLINE static void

                  نوشته اصلی توسط رضا آقازاده
                  جواب من بدرد نخورد یا کتاب بهتری میخوایین؟


                  ممنون از جوابتون
                  من اینطور متوجه شدم که inline یعنی بجای فراخوانی شدن کپی میشود
                  حالا inline__ یعنی چی /چه فرقی با inline داره
                  در ضمن ماکرو چی هست

                  stack چی هست
                  حالا چرا تو تعریف تابع inline stack void تعریف شده

                  مببینی همه چیش برام سواله

                  دیدگاه


                    #10
                    پاسخ : __INLINE static void

                    inline__ همون inline هست. چون این دستور یک دستور استاندارد زبان C نیست بخاطر استاندارد کردن موارد توسعه ای زبان C پیشوند __ قبل از اون آورده میشه.
                    ماکرو همون فرم هایی مثل تابع هست که شما توسط دستورات پیش پردازشی استفاده میکنین مثل:

                    #define min(a,b) (((a)<(b))?(a):(b))


                    همونطور که میبینین این یک جورایی عین یک تابع رفتار میکنه اما نوعی برای a و b تعریف نشده. بنا براین آرگومانهای اون بودن نوع هستن. و در اصل وقتی مینویسیم:

                    min(5,7)


                    کامپایلر قبل از شروع به کامپایل اون رو با عبارت زیر تعویض میکنه:

                    (((5)<(7))?(5):(7))


                    یک جایگزینی ساده. ولی کارا.

                    static مشخص میکنه که این تابع فقط داخل همین سورس جاری استفاده میشه و جای دیگه ای نباید شناخته بشه.

                    void یعنی مقدار برگشتی تابع مشخص نیست یا به زبانی دیگه تابع مقدار برگشتی نداره.

                    اگر معنی استک یا پشته رو هم نمیدونی که بهتره یک کتاب C (هر چی باشه) گیر بیاری و درست مطالعه کنی چون مشخصا ساختارهای حافظه رو نمیدونی. اگر هم حالش نبود بگو یه جوری از خجالتت در بیاییم.
                    :mrgreen:
                    فقط یه کمی باید قصه حسن کچل تعریف کنم. منطق هاش ساده هست. مسلما براحتی متوجه میشی. فقط باید قصه رو گوش بدی. همین.

                    دیدگاه


                      #11
                      پاسخ : __INLINE static void

                      ممنون
                      خیلی خوب بود
                      آخه تو کتاب آسمون ریسمون بهم می بافن
                      در باره ساختار حافظه هم ی توضیح مختصر بدین ممنون میشم

                      دیدگاه


                        #12
                        پاسخ : __INLINE static void

                        وقتی یک برنامه مینویسین (زمان کامپایل) فقط دو قسمت در فایل اجرایی شما ایجاد میشه. قسمتی که حاوی کد و دستورالعمل های اجرایی برنامه هست و قسمتی که حاوی اطلاعات و متغیر های عمومی (که بیرون توابع تعریف میکنین) که بهش میگیم data.
                        وقتی برنامه شروع به اجرا میشه سیستمتون یک میزان حافظه آزاد داره که اگر از مجموع حجم کد و دیتا کمتر باشه اصلا برنامه در حافظه بار نمیشه. اما یک میزان خاصی حافظه هم جدا از کد و داده برای اجرا مورد نیاز هست که بهش میگیم پشته. یا همون stack. که متغیر هایی که درون تابع تعریف میشه و آدرس برگشت تابع و پارامترهایی که به یک تابع پاس میشه اینجا قرار میگیره. این یک حافظه مشترک بین تمام توابع هست و مثل یک خشاب عمل میکنه. وقتی چیزی به یک تابع پاس میشه؛ داخل این خشاب چیزی قرار میگیره. وقتی تابع صدا زده میشه باز از این خشاب استفاده میشه. در حالت عکس هنگام برگشت از تابع این اطلاعات از خشاب برداشته میشه و این خشاب که بهش میگیم استک خالی میشه.

                        برای اطلاع بیشتر؛ معمولا سیستم شما میزان حافظه ای به مراتب بیشتر از میزان data و stack داره که این حافظه اضافه رو بهش heap میگیم. که فعلا باهاش کاری نداریم.

                        دیدگاه

                        لطفا صبر کنید...
                        X