לוגו אתר Fresh          
 
 
  אפשרות תפריט  ראשי         אפשרות תפריט  מבזקים     אפשרות תפריט  צור קשר     חץ שמאלה חץ ימינה  

לך אחורה   לובי הפורומים > מחשבים > תוכנה ומשחקי מחשב
שמור לעצמך קישור לדף זה באתרי שמירת קישורים חברתיים
תגובה
 
כלי אשכול חפש באשכול זה



  #1  
ישן 22-02-2016, 14:05
צלמית המשתמש של Musicman0
  משתמש זכר Musicman0 Musicman0 אינו מחובר  
 
חבר מתאריך: 25.12.05
הודעות: 4,997
בעיה מוזרה בVisual studio - מוציא פלט שגוי

היי

יש לי בעיה ממש הזויה בVisual Studio 2013 Express.

הוא נותן פלטים שגויים.
מה זאת אומרת?


בימים האחרונים אני לומד למבחן בC++ ועובר על שאלות בסגנון של "מה יהיה הפלט בתוכנית הבאה".
ו-וואלה, בבדיקה הרצה בקומפלייר, הוא נותן פלט שגוי/אחר.

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


איך זה יכול להיות?
הרי אם אובייקט לא צריך לעבור בdestructor למשל (כי לא נוצר אובייקט מלכתחילה), אז הוא לא יעבור. נקודה.


אשמח לעזרה
כי זה די מקשה עלי ככה ללמוד ולעבוד
תודה
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה

תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #7  
ישן 23-02-2016, 22:09
צלמית המשתמש של Musicman0
  משתמש זכר Musicman0 Musicman0 אינו מחובר  
 
חבר מתאריך: 25.12.05
הודעות: 4,997
בתגובה להודעה מספר 1 שנכתבה על ידי Musicman0 שמתחילה ב "בעיה מוזרה בVisual studio - מוציא פלט שגוי"

לא צירפתי קוד כי זה לא משהו ספציפי אלא קורה לעיתים די קרובות לאחרונה.

אבל אתן דוגמה מאוד פשוטה. בסה"כ מעבר בבנאים ומפרקים.

מה הקוד מדפיס?

קוד PHP:
 #include <iostream>
using namespace std;


class 
A
{
public:
    
A() { cout << "A's Ctor" << endl; }
    ~
A() { cout << "A's Dtor" << endl; }
    const 
char *what() const { return "Exception in A"; }
};
class 
B
{
public:
    
B() { cout << "Bs ctor" << endl; }
    ~
B() { cout << "B dtor" << endl; }
};

void MyFunc()
{
    
B b;
    throw 
A();
}

void main()
{
    try
    {
        
MyFunc();
    }
    catch (
A a)
    {
        
cout << a.what() << endl;
    }
    catch (
char *str)
    {
        
cout << "Caught some other ex " << str << endl;
    }





אמור להדפיס
Bs ctor
A's Ctor
B dtor
Exception in A
A's Dtor
A's Dtor

אצלי מדפיס
Bs ctor
A's Ctor
A's Dtor
B dtor
Exception in A
A's Dtor
A's Dtor
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה

תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה


נערך לאחרונה ע"י Musicman0 בתאריך 23-02-2016 בשעה 22:12.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #8  
ישן 24-02-2016, 12:22
צלמית המשתמש של קוביבי
  משתמש זכר קוביבי קוביבי אינו מחובר  
מנהל פורום מערכות הפעלה - הרובע המייקרוסופטי.
 
חבר מתאריך: 07.10.04
הודעות: 13,777
LinkedIn profile
בתגובה להודעה מספר 7 שנכתבה על ידי Musicman0 שמתחילה ב "לא צירפתי קוד כי זה לא משהו..."

אוקיי,
אני מבין שזו הרצה עם F5
נסה להריץ עם ctrl+F5
נסה להריץ את הexe שנוצר
נסה לשים breakpoint על הdtor של A, בכול פעם שמגיע תראה מה הcall stack, תבדוק מה הכתובת של האובייקט (כדי לאמת את ההימור שלי בהמשך)

בכלל, התוצאה אצלך לא שונה יותר מידי ממה ש"צריך להיות", רק קריאה לdtor יותר מפעם אחת.
אני לא זוכר את הנושא הזה יותר מידי, אבל נראה שאתה מצפה שהthrow יעביר את הנתון byref (ובכך לא נצטרך לקרוא לdtor) אבל למעשה הוא מועבר byval, אני עדיין אהמר על compiler optimization, אני לא מצליח לחשוב על סיבה שזה יעבוד אחרת.
http://stackoverflow.com/questions/...timization-in-c

מאפייני הפרויקט - כפתור יומני על הפרוייקט + properties
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #9  
ישן 24-02-2016, 17:52
צלמית המשתמש של Musicman0
  משתמש זכר Musicman0 Musicman0 אינו מחובר  
 
חבר מתאריך: 25.12.05
הודעות: 4,997
בתגובה להודעה מספר 8 שנכתבה על ידי קוביבי שמתחילה ב "אוקיי, אני מבין שזו הרצה עם..."

* האמת שאני מריץ עם ctrl+F5.
אף פעם הרצה עם F5 לבד לא ממש עבדה (חלונית נפתחת ונסגרת).

* מוזר, אבל כשאני ניגש ישירות לקובץ EXE שבתיקיית DEBUG לא ניתן להריץ אותו. הוא נפתח ונסגר (כמו בהרצה עם F5).

* לגבי ה call stack. מקווה שאני מבין אותך ואם לא אשמח להסבר עבור עילג כמוני שלא מתמצא בVS.
כשאני מגיע לdestructor של A הכתובת של האובייקט (ה this) הוא 0x00000103 - זה ב locals.
ב call stack עצמו יש את הדבר הבא:
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה

מה שקורה בתכנית בזמן ריצה (לפחות למיטב הבנתי), זה שהוא מגיע לפונקציה, ומייצר אובייקט A ( ב throw עצמו) - ועובר ב A c'tor. מכיוון שהתפיסה היא של אובייקט A by val אז הוא מייצר עוד A (שולח העתק בעצם).
אז בנקודה הזאת יש שני אובייקטים A שקיימים, ולכן בסוף התוכנית עובר פעמיים ב
A d'tor (אבל משום מה עובר גם פעם נוספת באמצע התוכנית).

בהתחלה חשבתי שאולי פעמיים נוצרו העתקים של A, כך שיש 3 אובייקטים A במהלך התכנית
אבל זה לא מה שקורה. בתכנית נוצרו רק פעמיים אובייקט מסוג A


* מאפייני פרויקט
https://2016-uploaded.fresh.co.il/2...24/42807388.jpg
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה

תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה


נערך לאחרונה ע"י Musicman0 בתאריך 24-02-2016 בשעה 18:06.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #11  
ישן 27-02-2016, 23:08
צלמית המשתמש של פסטן
  פסטן פסטן אינו מחובר  
 
חבר מתאריך: 14.12.09
הודעות: 9,590
בתגובה להודעה מספר 7 שנכתבה על ידי Musicman0 שמתחילה ב "לא צירפתי קוד כי זה לא משהו..."

ציטוט:
במקור נכתב על ידי Musicman0
לא צירפתי קוד כי זה לא משהו ספציפי אלא קורה לעיתים די קרובות לאחרונה.

אבל אתן דוגמה מאוד פשוטה. בסה"כ מעבר בבנאים ומפרקים.

מה הקוד מדפיס?

קוד PHP:
 #include <iostream>
using namespace std;


class 
A
{
public:
    
A() { cout << "A's Ctor" << endl; }
    ~
A() { cout << "A's Dtor" << endl; }
    const 
char *what() const { return "Exception in A"; }
};
class 
B
{
public:
    
B() { cout << "Bs ctor" << endl; }
    ~
B() { cout << "B dtor" << endl; }
};

void MyFunc()
{
    
B b;
    throw 
A();
}

void main()
{
    try
    {
        
MyFunc();
    }
    catch (
A a)
    {
        
cout << a.what() << endl;
    }
    catch (
char *str)
    {
        
cout << "Caught some other ex " << str << endl;
    }





אמור להדפיס
Bs ctor
A's Ctor
B dtor
Exception in A
A's Dtor
A's Dtor

אצלי מדפיס
Bs ctor
A's Ctor
A's Dtor
B dtor
Exception in A
A's Dtor
A's Dtor


הנה, גם GCC מדפיס את השורה שסימנת: http://codepad.org/9k6nZPVw

למה נראה לך שזה מה שהוא אמור להדפיס? אתה תופס את החריגה by value וזה אומר שיוצרים עותק, כמו שכשמעבירים פרמטר לפונקציה by value יוצרים עותק. הקומפיילר רשאי לבצע copy elision, אבל ממש ממש לא חייב.

יתר על כן, הייתה בעיה בתקן שבגללה לא היה ברור אם ותחת אליו תנאים מותר לבצע copy elision של חריגות שתוקנה ב-C++11. קישורים:
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה(קרדיט למרשי)
אמר לה ינאי מלכא לדביתיה אל תתיראי מן הפרושין ולא ממי שאינן פרושין אלא מן הצבועין שדומין לפרושין שמעשיהן כמעשה זמרי ומבקשין שכר כפנחס

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

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #12  
ישן 28-02-2016, 17:30
צלמית המשתמש של Musicman0
  משתמש זכר Musicman0 Musicman0 אינו מחובר  
 
חבר מתאריך: 25.12.05
הודעות: 4,997
בתגובה להודעה מספר 11 שנכתבה על ידי פסטן שמתחילה ב "[QUOTE=Musicman0]לא צירפתי..."

מוזר..
אני בדקתי פה והפלט הוא אחר
http://cpp.sh/8t45q

ואני מבין שהוא יוצר העתק כי הוא תופס BY VALUE
אבל הוא יוצר פעם אחת העתק
ופעם אחת נבנה "רגיל"
כלומר יהיו בסה"כ שני אובייקטים. ובמהלך התוכנית הוא עובר 3 פעמים בDestructor.

אשמח להסבר איך זה קורה. כי אני מפספס פה משהו..

על מנת לראות שאני לא טועה, מימשתי בנאי העתקה סטנדרטי, שבעצם לא עושה כלום חוץ מהדפסה ("להראות נוכחות" בפלט)
אז יש מעבר פעם אחת ב A's Ctor
ופעם אחת מעבר ב A's copy ctor.

שני אובייקטים סה"כ. 3 פעמים מעבר במפרק (?)


ציטוט:
במקור נכתב על ידי פסטן
אתה טוען שאם תיקח את הפרויקט, תעתיק אותו למחשב אחר עם אותה גרסת VC בדיוק ותבנה אותו שם תקבל את פלט שונה? קשה לי להאמין.

גרסה אחרת של VISUAL..


כל מי שבדקתי אצלו בכיתה שמשתמש בגרסת VS אחרת, השורה לא הופיעה.
(Ultimate או משהו אחר)
אני היחיד שהשורה הזו הודפסה אצלו

עכשיו אני מבין שזה נובע ומושפע מהגרסא ומהתקן. אבל שוב, אני אשמח שתסביר לי
איך נוצרו 2 אובייקטים, אבל 3 פעמים יש מעבר ב מפרק


תודה!
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה

תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #13  
ישן 28-02-2016, 17:46
צלמית המשתמש של פסטן
  פסטן פסטן אינו מחובר  
 
חבר מתאריך: 14.12.09
הודעות: 9,590
בתגובה להודעה מספר 12 שנכתבה על ידי Musicman0 שמתחילה ב "מוזר.. אני בדקתי פה והפלט..."

ציטוט:
במקור נכתב על ידי Musicman0
מוזר..
אני בדקתי פה והפלט הוא אחר
http://cpp.sh/8t45q

ואני מבין שהוא יוצר העתק כי הוא תופס BY VALUE
אבל הוא יוצר פעם אחת העתק
ופעם אחת נבנה "רגיל"
כלומר יהיו בסה"כ שני אובייקטים. ובמהלך התוכנית הוא עובר 3 פעמים בDestructor.

אשמח להסבר איך זה קורה. כי אני מפספס פה משהו..

על מנת לראות שאני לא טועה, מימשתי בנאי העתקה סטנדרטי, שבעצם לא עושה כלום חוץ מהדפסה ("להראות נוכחות" בפלט)
אז יש מעבר פעם אחת ב A's Ctor
ופעם אחת מעבר ב A's copy ctor.

שני אובייקטים סה"כ. 3 פעמים מעבר במפרק (?)



גרסה אחרת של VISUAL..


כל מי שבדקתי אצלו בכיתה שמשתמש בגרסת VS אחרת, השורה לא הופיעה.
(Ultimate או משהו אחר)
אני היחיד שהשורה הזו הודפסה אצלו

עכשיו אני מבין שזה נובע ומושפע מהגרסא ומהתקן. אבל שוב, אני אשמח שתסביר לי
איך נוצרו 2 אובייקטים, אבל 3 פעמים יש מעבר ב מפרק


תודה!

כנראה שאם עברו 3 פעמים במפרק זה אומר שנוצרו 3 אובייקטים ולא 2. מי אמר שנוצרו 2? אתה.
בוא נשאל את התוכנה כמה פעמים נוצרו אובייקטים מהטיפוס הזה: http://codepad.org/fHmH1cmg
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה(קרדיט למרשי)
אמר לה ינאי מלכא לדביתיה אל תתיראי מן הפרושין ולא ממי שאינן פרושין אלא מן הצבועין שדומין לפרושין שמעשיהן כמעשה זמרי ומבקשין שכר כפנחס

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

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #16  
ישן 28-02-2016, 21:04
צלמית המשתמש של פסטן
  פסטן פסטן אינו מחובר  
 
חבר מתאריך: 14.12.09
הודעות: 9,590
בתגובה להודעה מספר 15 שנכתבה על ידי borsood שמתחילה ב "כן. בתקנים החדשים של C++..."

ציטוט:
במקור נכתב על ידי borsood
כן. בתקנים החדשים של C++ המהדר רשאי, אך לא חייב לעשות אופטימיזציות בבנאי העתקה ובנאי הזזה, כולל כאלו שמשנות התנהגות (side effects).
ההחלטה מה המהדר יעשה תלויה במימוש שלו, בתצורה (שגורמת לאותה גרסה להתנהג אחרת), ובדגלים שמעבירים למהדר.

האמת שהוא היה רשאי לעשות את זה מאז ומעולם (לא כולל move constructors שלא היו קיימים, כמובן).

כבר ב-ISO/IEC 14882:1998 (התקן הראשון של CPP, אני מזכיר) ב-§12.8p15 נאמר:
Whenever a temporary class object is copied using a copy constructor, and this object and the copy have the
same cv-unqualified type, an implementation is permitted to treat the original and the copy as two different
ways of referring to the same object and not perform a copy at all, even if the class copy constructor or
destructor have side effects. For a function with a class return type, if the expression in the return statement
is the name of a local object, and the cv-unqualified type of the local object is the same as the function
return type, an implementation is permitted to omit creating the temporary object to hold the function return
value, even if the class copy constructor or destructor has side effects. In these cases, the object is
destroyed at the later of times when the original and the copy would have been destroyed without the optimization.

וכנ"ל הניסוחים ה"בעייתיים" לגבי חריגות ב-§15.1p5 וב-§15.3p18.
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה(קרדיט למרשי)
אמר לה ינאי מלכא לדביתיה אל תתיראי מן הפרושין ולא ממי שאינן פרושין אלא מן הצבועין שדומין לפרושין שמעשיהן כמעשה זמרי ומבקשין שכר כפנחס

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

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #17  
ישן 28-02-2016, 20:55
צלמית המשתמש של פסטן
  פסטן פסטן אינו מחובר  
 
חבר מתאריך: 14.12.09
הודעות: 9,590
בתגובה להודעה מספר 14 שנכתבה על ידי Musicman0 שמתחילה ב "לא אני.. הויז'ואל..."

ציטוט:
במקור נכתב על ידי Musicman0
לא אני..
הויז'ואל שלי:

https://2016-uploaded.fresh.co.il/2...28/69766933.jpg

אני עוד לא מספיק מומחה כדי לטעון דברים כאלו ואחרים


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

ציטוט:
במקור נכתב על ידי Musicman0
וזה יותר חיזק את מה שחשבתי.
חשבתי שהמעבר ב A's dtor ב"אמצע" שם, הוא לא באמת מעבר במפרק.. רק באג בויז'ואל
כי תראה מה הפלט עכשיו
הדפסה של מפרק הוחלפה בהדפסה של העתקה
כלומר יוצר אחד, מעתיק אחד, ומפרק שניים.
אבל זה עדיין לא הפלט שיוצא בGCC, ועדיין לא מראה שעובר פעמיים בבנאי העתקה.

איך זה יכול להיות?
אם עצם זה שהוספתי מימוש לבנאי העתקה העלים לי הדפסה אחת של בנאי מפרק?

איך יכול להיות? ככה. זה מה שכתבתי למעלה. הקומפיילר רשאי לחסוך העתקות (בתנאים מסוימים) וליצור את האובייקט ישר איפה שהוא יהיה בסוף. הוא לא חייב. מסתבר שבגרסה המסוימת של VC שיש לך כשלא מימשת את ה-copy constructor הוא החליט ככה וכשמימשת הוא החליט אחרת. אולי קצת מוזר, אבל זכותו.
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה(קרדיט למרשי)
אמר לה ינאי מלכא לדביתיה אל תתיראי מן הפרושין ולא ממי שאינן פרושין אלא מן הצבועין שדומין לפרושין שמעשיהן כמעשה זמרי ומבקשין שכר כפנחס

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

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #19  
ישן 28-02-2016, 21:51
צלמית המשתמש של פסטן
  פסטן פסטן אינו מחובר  
 
חבר מתאריך: 14.12.09
הודעות: 9,590
בתגובה להודעה מספר 18 שנכתבה על ידי Musicman0 שמתחילה ב "אוקיי, החכמתי אז שאלת..."

ציטוט:
במקור נכתב על ידי Musicman0
אוקיי, החכמתי

אז שאלת השאלות
במבחן מופיע הקוד הנ"ל כשאלה אמריקאית ושואלים מה הפלט
איזה תשובה אני מקיף?
מבחינת הבודק יש רק תשובה אחת נכונה.
נניח והנוסח לא היה אמריקאי, איזה פלט אני אמור לכתוב?
כי כביכול גם זה נכון, וגם זה נכון. (יכול להדפיס את זה, ויכול להדפיס גם את זה..)


נ.ב
שורה תחתונה הVisual Studio שלי "תקין" ואפשר לשחרר את הפניקה ואין צורך להחליף גרסה?

לא יודע. זו שאלה שאתה צריך לפתור מול המרצה שלך.

(יש משהו קצת מוזר בפלט של VC שכולל את ה-copy constructor-ים, אבל הפלט רק עם הבנאים הרגילים תקין לגמרי.)

אם השאלה לא אמריקאית, תבחר איזה שבא לך ותוסיף בהערה שהקומפיילר רשאי להעיף חלק מההעתקות. אני הייתי כותב את הצורה עם 3 האובייקטים, כי זה מה שקורה עקרונית, לפני שנכנסים לאפטימיזציות. אבל שוב, אם המרצה לימד אותך ש"צריך לכתוב ככה", אז תכתוב מה שהמרצה לימד.
_____________________________________
תמונה שהועלתה על ידי גולש באתר ולכן אין אנו יכולים לדעת מה היא מכילה(קרדיט למרשי)
אמר לה ינאי מלכא לדביתיה אל תתיראי מן הפרושין ולא ממי שאינן פרושין אלא מן הצבועין שדומין לפרושין שמעשיהן כמעשה זמרי ומבקשין שכר כפנחס

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

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
תגובה

כלי אשכול חפש באשכול זה
חפש באשכול זה:

חיפוש מתקדם
מצבי תצוגה דרג אשכול זה
דרג אשכול זה:

מזער את תיבת המידע אפשרויות משלוח הודעות
אתה לא יכול לפתוח אשכולות חדשים
אתה לא יכול להגיב לאשכולות
אתה לא יכול לצרף קבצים
אתה לא יכול לערוך את ההודעות שלך

קוד vB פעיל
קוד [IMG] פעיל
קוד HTML כבוי
מעבר לפורום



כל הזמנים המוצגים בדף זה הם לפי איזור זמן GMT +3. השעה כעת היא 01:21

הדף נוצר ב 0.50 שניות עם 10 שאילתות

הפורום מבוסס על vBulletin, גירסא 3.0.6
כל הזכויות לתוכנת הפורומים שמורות © 2017 - 2000 לחברת Jelsoft Enterprises.
כל הזכויות שמורות ל Fresh.co.il ©

צור קשר | תקנון האתר