socket-programming:perror
تفاوتها
تفاوت دو نسخهٔ متفاوت از صفحه را مشاهده میکنید.
| socket-programming:perror [2024/06/18 00:26] – ایجاد شد pejman | socket-programming:perror [2024/06/18 00:58] (فعلی) – حذف شد pejman | ||
|---|---|---|---|
| خط 1: | خط 1: | ||
| - | ====== تابع ()perror ====== | ||
| - | |||
| - | اکثر توابع Network API هنگامی که با خطایی مواجه می شوند، یک متغییر global به نام errno را مقدار دهی میکنند که این متغییر توسط [[perror]] به error message های قابل نمایش تبدیل میشود: | ||
| - | |||
| - | <code C> | ||
| - | #include < | ||
| - | #include < | ||
| - | |||
| - | void perror(const char *s); | ||
| - | </ | ||
| - | |||
| - | این تابع ابتدا رشته s و سپس پیغام مربوط به آخرین خطای رخ داده را نمایش میدهد. | ||
| - | |||
| - | در عمل چون تعداد فراخوانی های [[perror]] زیاد است، برای فراخوانی آن از یک تکنیک بسیار جالب استفاده می شود. ابتدا یک ماکرو به شکل زیر تعریف شده : | ||
| - | |||
| - | <code C> | ||
| - | // man 2 bind | ||
| - | #define handle_error(msg) \ | ||
| - | do { perror(msg); | ||
| - | </ | ||
| - | |||
| - | و سپس در برنامه با این شکل استفاده می شود : | ||
| - | <code C> | ||
| - | if (sockfd == -1) | ||
| - | handle_error(" | ||
| - | </ | ||
| - | |||
| - | برای توضیح وجود do{....}while(0) در ماکرو باید گفت که این تکنیک کمک میکند این ماکرو در شرایط مختلف قابل استفاده و درست باشد. در مثال زیر : | ||
| - | |||
| - | <code C> | ||
| - | #include < | ||
| - | #include < | ||
| - | #include < | ||
| - | #include < | ||
| - | #include < | ||
| - | #include < | ||
| - | #include < | ||
| - | |||
| - | #define handle_error(msg) \ | ||
| - | do { perror(msg); | ||
| - | |||
| - | int main() | ||
| - | { | ||
| - | int sockfd; | ||
| - | |||
| - | sockfd = socket(0, 0, 0); | ||
| - | |||
| - | if (sockfd == -1) | ||
| - | handle_error(" | ||
| - | else | ||
| - | printf(" | ||
| - | |||
| - | return 0; | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | اگر ماکرو به این شکل تعریف شود : | ||
| - | |||
| - | <code C> | ||
| - | #define handle_error(msg) \ | ||
| - | perror(msg); | ||
| - | </ | ||
| - | |||
| - | کد توسط preprocessor به این شکل تبدیل شده | ||
| - | <code C> | ||
| - | if (sockfd == -1) | ||
| - | perror(msg); | ||
| - | else | ||
| - | printf(" | ||
| - | </ | ||
| - | |||
| - | حتی اگر از { } کمک بگیریم و به این شکل ماکرو را تعریف کنیم : | ||
| - | |||
| - | <code C> | ||
| - | #define handle_error(msg) \ | ||
| - | { perror(msg); | ||
| - | </ | ||
| - | |||
| - | این بار کد توسط preprocessor به شکل زیر تبدیل شده و بخاطر ; بعد از { باز هم بین if و else فاصله ایجاد شده و ترجمه نخواهد شد : | ||
| - | |||
| - | <code C> | ||
| - | if (sockfd == -1) | ||
| - | { perror(msg); | ||
| - | else | ||
| - | printf(" | ||
| - | </ | ||
| - | |||
| - | غیر از روش do{....}while(0) با کمک if(1){....}else و با کمک comma operator هم می توان این مشکل را حل کرد. البته comma operator بسیار محدود است و در موقعیتهای ساده کار آمد خواهد بود : | ||
| - | |||
| - | <code C> | ||
| - | #define handle_error(msg) \ | ||
| - | if(1) { perror(msg); | ||
| - | |||
| - | #define handle_error(msg) \ | ||
| - | perror(msg), | ||
| - | |||
| - | </ | ||
| - | |||
| - | برای بررسی خروجی preprocessor می توان از E- در gcc استفاده کرد : | ||
| - | |||
| - | gcc -E file.c | ||
| - | |||
| - | |||
socket-programming/perror.1718657794.txt.gz · آخرین ویرایش: 2024/06/18 00:26 توسط pejman
