Solving VC++ Express Compiler Discrepancy with Conditional Operator

  • Context: C/C++ 
  • Thread starter Thread starter sid_galt
  • Start date Start date
Click For Summary

Discussion Overview

The discussion revolves around discrepancies encountered when using the VC++ Express compiler, particularly related to the conditional operator and the sizeof operator in C++. Participants explore issues with code behavior and struct size calculations, examining both compiler-specific behavior and coding practices.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant reports that their initial code using if statements resulted in unexpected behavior, with all sum values being converted to 1.0, while the conditional operator worked correctly.
  • Another participant points out a missing semicolon in the original code, suggesting it could be a source of the issue.
  • Some participants speculate that the problem may lie in the unspecified "whatever" code or suggest the possibility of a compiler bug.
  • A participant introduces a more compact version of the conditional logic using nested ternary operators, noting that such constructs may not be favored in coding standards.
  • Discussion shifts to a new problem regarding the size of a struct, where one participant notes that the sizeof operator returns 16 bytes instead of the expected 11 bytes, prompting inquiries about data alignment and padding.
  • Another participant explains that alignment requirements likely cause the discrepancy in the struct size, suggesting reordering the struct members for optimal size.

Areas of Agreement / Disagreement

Participants express differing views on the cause of the initial code's behavior, with some attributing it to coding errors and others suggesting compiler-related issues. The struct size discussion also reveals a lack of consensus on the implications of data alignment.

Contextual Notes

Participants mention that the behavior of the code may be compiler-dependent, and the discussion includes assumptions about data alignment and padding that are not universally applicable.

Who May Find This Useful

Programmers working with C++ who encounter compiler discrepancies, those interested in struct memory layout and optimization, and individuals exploring the nuances of conditional operators in coding.

sid_galt
Messages
503
Reaction score
1
My VC++ Express compiler has been acting very funnily of late.

I tried the following code
Code:
for(whatever)
{
double sum = whatever;

if(sum > 5.0)
    sum = 5
else if(sum < 1.0)
    sum = 1
}

The problem with this was that the program was now converting all the sum values generated into 1.0, even those which were greater than 1.0.

Instead of using the if statement, I tried the conditional operator and then it worked fine.

Code:
for(whatever)
{
double sum = whatever;

sum = sum > 5?  5:sum;
sum = sum < 1?  1:sum;
}//Working Okay

Does anyone know the reason for this discrepancy?
 
Technology news on Phys.org
Well for one thing, you forgot the ';' after sum=5 / sum=1 in the first code.
 
Seriously, I think the problem must be in the "whatever" (the code you didn't post). Either that, or you found a bug in the compiler.

In any case, the code below would be far more elegant (C++ jargon for cryptic :-)

sum = (sum > 5) ? 5 : ((sum < 1) ? 1 : sum);
 
nabuco said:
Seriously, I think the problem must be in the "whatever" (the code you didn't post). Either that, or you found a bug in the compiler.

In any case, the code below would be far more elegant (C++ jargon for cryptic :-)

sum = (sum > 5) ? 5 : ((sum < 1) ? 1 : sum);

Most coding standards will fail nested ternary statements on code reviews. So try to keep it on your lab box. :-)
 
Thanks for the replies.

Actually, the statements inside the for loop constitute an inline function. This inline function is what is actually called repeatedly through the for loop. The whatever is nothing but a simple for loop (int i = 0; i < ratingCount; i++)
I am getting another problem, this time both in VC++ and g++. I have created a structure -
Code:
typedef  unsigned char BYTE;

struct Data
{
short MovieId;
int CustId;
BYTE Rating;
float cache;
} rt;

cout<<sizeof(rt)<<endl;  //gives 16
cout<<sizeof(short)+sizeof(int)+sizeof(BYTE)+sizeof(float)<<endl; //correctly gives 11

When I use the sizeof() function to find out the size of the Data struct, it comes out to be 16 bytes instead of the 11 bytes it should be (2[short]+4[int]+1[BYTE aka char]+4[float]).
When I summed up the individual sizes of the variables inside the struct using sizeof(float), etc., the size was correctly coming to be 11 bytes.
 
Last edited:
sid_galt said:
Actually, the statements inside the for loop constitute an inline function.
I still don't really understand the code in your first post. Since you are facing a subtle, apparently compiler-dependent problem, you should post the code as written.
I am getting another problem, this time both in VC++ and g++. I have created a structure -
Code:
typedef  unsigned char BYTE;

struct Data
{
short MovieId;
int CustId;
BYTE Rating;
float cache;
} rt;

cout<<sizeof(rt)<<endl;  //gives 16
cout<<sizeof(short)+sizeof(int)+sizeof(BYTE)+sizeof(float)<<endl; //correctly gives 11

When I use the sizeof() function to find out the size of the Data struct, it comes out to be 16 bytes instead of the 11 bytes it should be (2[short]+4[int]+1[BYTE aka char]+4[float]).
When I summed up the individual sizes of the variables inside the struct using sizeof(float), etc., the size was correctly coming to be 11 bytes.

Almost certainly the float (and sounds like the int as well) has to be aligned on 4-byte boundaries. That means you have a 3 byte gap between the end of the char and the start of the float, etc. If you want you struct to have the smallest size, reorder the data elements so that the largest ones are first. This is a good rule to observe whenever coding a struct or class.
 
nmtim said:
I still don't really understand the code in your first post. Since you are facing a subtle, apparently compiler-dependent problem, you should post the code as written.

Code:
for(i = 0; i < m_nRatingCount; i++)

			{

				movieId = rating->MovieId;

				custId = rating->CustId;



				p = predictRating(rating->cache, UserFactor[f][custId], MovieFactor[f][movieId]);

				err = rating->Rating - p;

				sq += err*err;



				cf = UserFactor[f][custId];

				mf = MovieFactor[f][movieId];



				UserFactor[f][custId] += (float)(LRATE * (err * mf - K * cf));

				MovieFactor[f][movieId] += (float)(LRATE * (err * cf - K * mf));

				rating++;

			}

inline double predictRating(float &cache, float &UserFactor, float &MovieFactor)

{

	double sum = 0;

	sum = cache + UserFactor * MovieFactor;



	sum = sum > 5 ? 5:sum;//  This works but if condition does not

	sum = sum < 1 ? 1:sum;



	return sum;

}

Almost certainly the float (and sounds like the int as well) has to be aligned on 4-byte boundaries. That means you have a 3 byte gap between the end of the char and the start of the float, etc. If you want you struct to have the smallest size, reorder the data elements so that the largest ones are first. This is a good rule to observe whenever coding a struct or class.

Wow, I never knew that. Happily it worked.
 

Similar threads

  • · Replies 23 ·
Replies
23
Views
3K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 6 ·
Replies
6
Views
5K
Replies
1
Views
2K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 4 ·
Replies
4
Views
5K
  • · Replies 4 ·
Replies
4
Views
4K
  • · Replies 1 ·
Replies
1
Views
8K
  • · Replies 5 ·
Replies
5
Views
4K