انجمن‌های فارسی اوبونتو

کمک و پشتیبانی => برنامه‌سازی => نویسنده: ARH در 11 تیر 1388، 06:49 ب‌ظ

عنوان: یک سوال خفن در C
ارسال شده توسط: ARH در 11 تیر 1388، 06:49 ب‌ظ
سلام

آقا من که عقلم به جایی راه‌نمیده ! کسی میتونه بفهمه این یک تیکه کد چی چی داره می‌گه :
#define __READ_SPECMEM(SRC, SRC_V) \
  (addr = (SRC), \
   (spec_mode \
    ?   spec_mem_access(Read, addr, &SRC_V, sizeof(SRC_V))      \
    :  mem_access(Read, addr, &SRC_V, sizeof(SRC_V))),         \
   SRC_V)

البته خوب فکر کنم مشخصه که جای READ_SPECMEM میاد و اون یک تیکه کد رو می گذاره اما اگر فرض کنیم , (کاما) هم تو دستورات Pre-Compile معادل ; (سمی‌کولون) خودمونه خط آخرش اصلا معنی نمی‌ده !
عنوان: پاسخ به: یک سوال خفن در C
ارسال شده توسط: جادی در 11 تیر 1388، 08:55 ب‌ظ
با اپراتور ? توی سی آشنا هستی؟ اگر احیانن نه، یک نگاه به اینجا بنداز http://www.space.unibe.ch/comp_doc/c_manual/C/SYNTAX/conditional.html
عنوان: پاسخ به: یک سوال خفن در C
ارسال شده توسط: ARH در 11 تیر 1388، 09:05 ب‌ظ
با اپراتور ? توی سی آشنا هستی؟ اگر احیانن نه، یک نگاه به اینجا بنداز http://www.space.unibe.ch/comp_doc/c_manual/C/SYNTAX/conditional.html

نه مشکل اون اپراتور نیست ! مشکل اون , (کاما) ها هستند که من ازشون سر در نمی‌آورم ! ضمن اینکه تمام این کد با ماکروهای Pre-Compile نوشته شده
عنوان: پاسخ به: یک سوال خفن در C
ارسال شده توسط: سعید رسولی در 11 تیر 1388، 09:52 ب‌ظ
با اپراتور ? توی سی آشنا هستی؟ اگر احیانن نه، یک نگاه به اینجا بنداز http://www.space.unibe.ch/comp_doc/c_manual/C/SYNTAX/conditional.html

نه مشکل اون اپراتور نیست ! مشکل اون , (کاما) ها هستند که من ازشون سر در نمی‌آورم ! ضمن اینکه تمام این کد با ماکروهای Pre-Compile نوشته شده
بله. حق با شماست. کاما نقش سمی‌کالن رو داره. بنابراین کاری که این تابع انجام میده اینه که اول مقدار SRC رو می‌ریزه توی addr و بعدش با توجه به درست و غلط بودن spec_mode میاد یکی از توابع spec_mem_access و mem_access رو اجرا میکنه. فقط تنها مسئاله اینه که هدفش از اون قسمت سوم چی بوده، یعنی اون SRC_V آخر به نظر نمیاد کاری انجام بده!
یعنی به نظر میاد با این کد یکی هست:
#define __READ_SPECMEM(SRC, SRC_V) \
  (addr = SRC, \
  (spec_mode \
    ?   spec_mem_access(Read, addr, &SRC_V, sizeof(SRC_V))      \
    :  mem_access(Read, addr, &SRC_V, sizeof(SRC_V))) )
عنوان: پاسخ به: یک سوال خفن در C
ارسال شده توسط: ARH در 11 تیر 1388، 10:11 ب‌ظ
من هم تو همون خط آخر موندم ! وقتی دقیق تر شدم متوجه شدم این SRC_V در زمان اجرا به اسم یک متغییر  static اشاره میکنه ! حالا این که در خط اخر آوردن نام یک متغییر از نوع char چه معنی میتونه داشته باشه ؟
نکته جالب دیگه اینه که این تایع __READ_SPECMEM خروجی داره منظورم اینه که از خروجی این تابع استفاده شده است اما هر جفت توابع mem_access و spec_mem_access از نوع void هستند. اما مقدار اون SRC_V رو با اشاره‌گر Set می‌کنند ! حالا میشه اینطور استنباط کرد که خروجی تابع READ_SPECMEM رو همون خط آخر (متغییر SRC_V) تولید میکنه ! تغیریبا type هاشون هم به همدیگه می‌خوره !

عنوان: پاسخ به: یک سوال خفن در C
ارسال شده توسط: pedrambehroozi در 11 تیر 1388، 11:38 ب‌ظ
سلام

آقا من که عقلم به جایی راه‌نمیده ! کسی میتونه بفهمه این یک تیکه کد چی چی داره می‌گه :
#define __READ_SPECMEM(SRC, SRC_V) \
  (addr = (SRC), \
   (spec_mode \
    ?   spec_mem_access(Read, addr, &SRC_V, sizeof(SRC_V))      \
    :  mem_access(Read, addr, &SRC_V, sizeof(SRC_V))),        \
   SRC_V)

البته خوب فکر کنم مشخصه که جای READ_SPECMEM میاد و اون یک تیکه کد رو می گذاره اما اگر فرض کنیم , (کاما) هم تو دستورات Pre-Compile معادل ; (سمی‌کولون) خودمونه خط آخرش اصلا معنی نمی‌ده !

منم به یه همچین کدی برخورد کردم. تا جایی که من می دونم، این کد معادله با این کد:
#define __READ_SPECMEM(SRC, SRC_V)    \
do {    \
    addr = SRC;    \
    spec_mode ? spec_mem_access(READ, addr, &SRC_V, sizeof(SRC_V) :  mem_access(Read, addr, &SRC_V, sizeof(SRC_V))   \
    SRC_V;    \
} while(0)

و اگه این قضیه درست باشه، خط SRC_V; اصلا کامپایل نمیشه!
من کد زیر رو کامپایل کردم:
int a = 1;
a;
هیچ کد اسمبلی به ازای خط آخر تولید نمیشه!

این فرضیه هم که ممکنه خروجی تابع باشه رد میشه چون کدی که من دیدم تابعش هیچ خروجی نداشت.
شاید اگه توی یه فروم تخصصی C بپرسی زودتر جواب بگیری.
به هرحال اگه جوابشو پیدا کردی به ما هم یه خبرب بده  ;)
عنوان: پاسخ به: یک سوال خفن در C
ارسال شده توسط: سعید رسولی در 12 تیر 1388، 07:52 ق‌ظ
من هم تو همون خط آخر موندم ! وقتی دقیق تر شدم متوجه شدم این SRC_V در زمان اجرا به اسم یک متغییر  static اشاره میکنه ! حالا این که در خط اخر آوردن نام یک متغییر از نوع char چه معنی میتونه داشته باشه ؟
نکته جالب دیگه اینه که این تایع __READ_SPECMEM خروجی داره منظورم اینه که از خروجی این تابع استفاده شده است اما هر جفت توابع mem_access و spec_mem_access از نوع void هستند. اما مقدار اون SRC_V رو با اشاره‌گر Set می‌کنند ! حالا میشه اینطور استنباط کرد که خروجی تابع READ_SPECMEM رو همون خط آخر (متغییر SRC_V) تولید میکنه ! تغیریبا type هاشون هم به همدیگه می‌خوره !
بله. بازم خودتون جواب خودتون رو دادید! ظاهراً همون مقدار آخر رو برمی‌گردونه. یعنی اون SRC_V از تابع return میشه. با تستهایی که انجام دادم که اینطور بود. حتی توی اون قسمت آخر مقداردهی کرده باشیم، بازم همون برگردونده میشه.
یعنی اگه اون قسمت سوم نباشه، تابع void خواهد شد و نمیشه ازش خروجی گرفت(و اگه بگیریم ارور میده و کامپایل نمیشه). یعنی نوع خروجی تابع رو نوع خروجی قسمت آخرش تعیین میکنه.

جالب بود. :)
این جور کدها(مثل همین توابع pre-compile) اگرچه خوانایی برنامه رو کم می‌کنن، ولی در performance تاثیر مثبت دارن(چون قبل از کامپایل با کد جایگزین میشن، و موقع اجرا زمان سربارگذاری از بین میره). ضمن اینکه میشه بعضی توابع ساده رو بصورت cross-type تعریف کرد، یعنی نوع آرگومان‌ها و خروجی تابع موقع تعریف مشخص نیست، بلکه موقع فراخوانی مشخص میشه. شبیه زبانهای اسکریپتی!