====== تابع ()perror ====== اکثر توابع Network API هنگامی که با خطایی مواجه می شوند، یک متغییر global به نام errno را مقدار دهی میکنند که این متغییر توسط [[perror]] به error message های قابل نمایش تبدیل میشود: #include #include void perror(const char *s); این تابع ابتدا رشته s و سپس پیغام مربوط به آخرین خطای رخ داده را نمایش میدهد. در عمل چون تعداد فراخوانی های [[perror]] زیاد است، برای فراخوانی آن از یک تکنیک بسیار جالب استفاده می شود. ابتدا یک ماکرو به شکل زیر تعریف شده : // man 2 bind #define handle_error(msg) \ do { perror(msg); exit(EXIT_FAILURE); } while (0) و سپس در برنامه با این شکل استفاده می شود : if (sockfd == -1) handle_error("socket"); برای توضیح وجود do{....}while(0) در ماکرو باید گفت که این تکنیک کمک میکند این ماکرو در شرایط مختلف قابل استفاده و درست باشد. در مثال زیر : #include #include #include #include #include #include #include #define handle_error(msg) \ do { perror(msg); exit(EXIT_FAILURE); } while(0) int main() { int sockfd; sockfd = socket(0, 0, 0); if (sockfd == -1) handle_error("socket"); else printf("I got a socket\n"); return 0; } اگر ماکرو به این شکل تعریف شود : #define handle_error(msg) \ perror(msg); exit(EXIT_FAILURE); کد توسط preprocessor به این شکل تبدیل شده و به دلیل فاصله بین if و else ترجمه نخواهد شد : if (sockfd == -1) perror(msg); exit(EXIT_FAILURE); else printf("I got a socket\n"); حتی اگر از { } کمک بگیریم و به این شکل ماکرو را تعریف کنیم : #define handle_error(msg) \ { perror(msg); exit(EXIT_FAILURE); } این بار کد توسط preprocessor به شکل زیر تبدیل شده و بخاطر ; بعد از { باز هم بین if و else فاصله ایجاد شده و ترجمه نخواهد شد : if (sockfd == -1) { perror(msg); exit(EXIT_FAILURE); }; else printf("I got a socket\n"); غیر از روش do{....}while(0) با کمک if(1){....}else و با کمک comma operator هم می توان این مشکل را حل کرد. البته comma operator بسیار محدود است و در موقعیتهای ساده کار آمد خواهد بود : #define handle_error(msg) \ if(1) { perror(msg); exit(EXIT_FAILURE); } else #define handle_error(msg) \ perror(msg), exit(EXIT_FAILURE) برای بررسی خروجی preprocessor می توان از E- در gcc استفاده کرد : gcc -E file.c