אף אחד לא משתמש בפיצ'ר הזה

18/02/2016
C++

מפתחים תמיד חושבים שהשינויים שהוכנסו בגירסא חדשה של ספריה לא באמת מפריעים לאף אחד, וממילא אין מצב שמישהו מסתמך על ההתנהגות השבורה של המערכת אז מה הבעיה לתקן. לפחות במקרה של qDebug, אני דווקא השתמשתי בפיצ'ר השבור, ויש מצב שאולי גם אתם.

1. הסיפור בקצרה

מאז ומעולם qDebug לא היה כלי טוב במיוחד להדפסות דיבג. כל פעם שניסיתם להדפיס מידע בינארי (או תווים שלא ניתנים להדפסה) הקוד ניסה להדפיסו וכשל. זה יצר מצבים מביכים כשמתכנתים ניסו להדפיס מחרוזות שכללו את הסימן \0 ואז בפלט המחרוזת נחתכה באמצע, וכמובן בלי שום זכר לתו \0 או לכל התווים שבאו אחריו, כמו שמתואר בשאלה הזו מ SO.

מי שכן רצה להדפיס מידע בינארי בתוך מחרוזת היה צריך לדאוג בעצמו לוודא שאין שם תווים שלא ניתן להדפיס, או לבצע quoting לבד לפני השליחה ל qDebug. לא נעים אבל גם לא נורא.

לקראת גירסא 5.4 הציע Koehne Kai להוסיף ל qDebug יכולת לבצע תרגום אוטומטי של תווים מיוחדים (quoting). אחרי דיון קצר הוחלט שההתנהגות החדשה טובה יותר ולכן תהפוך לברירת המחדל. כך כותב קאי בדיון:

I doubt any sane application on the assumption how QDebug formats QByteArray's with 0's in it :)

ברור שאף אחד לא מדפיס בכוונה מחרוזות עם אפסים באמצע כדי לראות את המחרוזת נחתכת, אבל גם לא ציפיתם שהם יסתפקו בתרגום התו \0 בלבד נכון?

2. איך זה נגמר

גירסא 5.4 של Qt מתרגמת באופן אוטומטי מגוון תווים לפני ההדפסה ב qDebug, בין השאר את תו המרכאות ותווי ירידת השורה. הקוד הבא מדפיס פלט שונה ב Qt 5.4 לעומת גירסאות ישנות יותר:

#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    QString str("Hello \" World");
    qDebug() << str;
    return 0;
}

 

עד גירסא 5.4 קיבלנו את הפלט:

"Hello " World"

אך החל מגירסא 5.4 נקבל את הפלט:

"Hello \" World"

 

3. חזרה להתנהגות הישנה

אם אתם בגירסא 5.4 או מאוחרת יותר ורוצים לקבל את ההתנהגות הישנה תצטרכו לשנות את הקוד שלכם ולהוסיף קריאה לפונקציה noquote. זה נראה כך:

#include <QCoreApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    QString str("Hello \" World");
    qDebug().noquote() << str;
    return 0;
}