كيفية التعامل مع -Wconversion تحذيرات من دول مجلس التعاون الخليجي؟
-
10-07-2019 - |
سؤال
وأنا بناء مشروعي مع العلم -Wconversion تحذير دول مجلس التعاون الخليجي. (دول مجلس التعاون الخليجي (ديبيان 4.3.2-1.1) 4.3.2) على 64BIT جنو / لينكس OS / الأجهزة. أنا وجدت أنه من المفيد في تحديد أين لقد خلط أنواع أو فقدت وضوح على النحو الذي ينبغي أن تستخدم أنواع.
وانها ليست مفيدة جدا في معظم الحالات الأخرى التي تنشط انها التحذيرات وأنا أسأل كيف أنا من المفترض أن التعامل مع هذه:
enum { A = 45, B, C }; /* fine */
char a = A; /* huh? seems to not warn about A being int. */
char b = a + 1; /* warning converting from int to char */
char c = B - 2; /* huh? ignores this *blatant* int too.*/
char d = (a > b ? b : c) /* warning converting from int to char */
ونظرا لنتائج غير متوقعة من الاختبارات المذكورة أعلاه (حالات a
وc
) أنا أسأل أيضا لهذه الاختلافات أن أوضح أيضا.
وتحرير: وهل الإفراط في الهندسة ليلقي كل هذه مع (char)
لمنع التحذير
وEdit2: بعض حالات إضافية (بعد يوم من الحالات المذكورة أعلاه):
a += A; /* warning converting from int to char */
a++; /* ok */
a += (char)1; /* warning converting from int to char */
وبصرف النظر عن ذلك، ما أنا أسأل هو شخصي وأود أن نسمع كيف البعض تعامل الناس مع التحذيرات التحويل في مثل هذه الحالات عندما تفكر في أن بعض المطورين ندعو ازالة <م> جميع م> التحذيرات .
والعياء:
وأحد الحلول الممكنة هو مجرد استخدام int
s بدلا من char
s أليس كذلك؟ حسنا في الواقع، ليس فقط أنها لا تتطلب المزيد من الذاكرة، فمن أبطأ أيضا، كما ثبت علبة من التعليمات البرمجية التالية. التعبيرات الرياضيات هي فقط هناك للحصول على التحذيرات عندما بنيت مع -Wconversion
. توليت نسخة باستخدام متغيرات char
سيرشح نفسه أبطأ من ذلك int
s باستخدام بسبب التحويلات، ولكن على نظام بلدي (64BIT ثنائي النواة II) النسخة int
أبطأ.
#include <stdio.h>
#ifdef USE_INT
typedef int var;
#else
typedef char var;
#endif
int main()
{
var start = 10;
var end = 100;
var n = 5;
int b = 100000000;
while (b > 0) {
n = (start - 5) + (n - (n % 3 ? 1 : 3));
if (n >= end) {
n -= (end + 7);
n += start + 2;
}
b--;
}
return 0;
}
وممر -DUSE_INT
لدول مجلس التعاون الخليجي لبناء نسخة كثافة من المقتطف أعلاه.
المحلول
وعندما تقول /* int */
تقصد انها تعطيك تحذيرا حول ذلك؟ أنا لا نرى أي تحذيرات على الإطلاق في هذا الرمز مع دول مجلس التعاون الخليجي 4.0.1 أو 4.2.1 مع -Wconversion
. المترجم هو تحويل هذه تتضمن التعدادات في الثوابت. وبما أن كل شيء معروف في وقت الترجمة، لا يوجد سبب لتوليد تحذير. المترجم يمكن أن أمثل من جميع الشكوك (وفيما يلي إنتل مع 4.2.1):
movb $45, -1(%rbp) # a = 45
movzbl -1(%rbp), %eax
incl %eax
movb %al, -2(%rbp) # b = 45 + 1
movb $44, -3(%rbp) # c = 44 (the math is done at compile time)
movzbl -1(%rbp), %eax
cmpb -2(%rbp), %al
jle L2
movzbl -2(%rbp), %eax
movb %al, -17(%rbp)
jmp L4
L2:
movzbl -3(%rbp), %eax
movb %al, -17(%rbp)
L4:
movzbl -17(%rbp), %eax
movb %al, -4(%rbp) # d = (a > b ? b : c)
وهذا هو دون تشغيل أمثل. مع أمثل، فإنه سيتم حساب ب د لك في وقت الترجمة وترميز ثابت للقيم النهائية (إذا كان يحتاج إليها في الواقع أي شيء). وهذه النقطة هي أن دول مجلس التعاون الخليجي عملت بالفعل لا يمكن أن يكون هناك مشكلة هنا لأن كل القيم الممكنة تناسب في char
.
وتحرير: اسمحوا لي أن تعديل هذا إلى حد ما. هناك خطأ ممكن في تخصيص b
، وسوف مترجم قبض أبدا، حتى لو كان معين. على سبيل المثال، إذا b=a+250;
، فإن هذا سيكون من المؤكد أن تجاوز b
لكن دول مجلس التعاون الخليجي لا تصدر تحذيرا. ذلك لأن المهمة لa
غير قانوني، a
هو char
، وانها مشكلتك (وليس المترجم) للتأكد من أن الرياضيات لا تجاوز في وقت التشغيل.
نصائح أخرى
وربما المترجم يمكن أن يرى بالفعل أن كل القيم تنسجم مع شار حتى لا يكلف نفسه عناء التحذير. أتوقع أن enum
إلى أن تحل الحق في بداية تجميع.