Jump to content
Sign in to follow this  
davidb

Clear Bit And Test Bit Failure

Recommended Posts

Hi,

 

Bug Description:

 

The clear_bit(var,num) and test_bit(var,num) macros fail if the var is larger than 8 bits and num is a variable. The set_bit and toggle_bit macros appear to work as expected. The macros were expanded into standard code to prove the point as shown in the following snippet.

If an intermediate variable is used then the code for testing a bit and clearing a bit will compile and work as expected as shown in the last two examples.

I haven't fully checked but I believe the all macros are OK if num is a constant (also optimises code as well).

 

Expected Behaviour:

 

Not sure if this is a bug or just the way it works but I would expect to be able to use the standard bit shift method with any length of variable no matter how large the generated code. If there is a limit I would also expect a warning.

 

while(1)																// Loop forever
{
unsigned short test_word;				// Test word
unsigned short x;					// Test bit result
unsigned short y;					// Temporary variable							
unsigned char bit_num;				// Bit number

test_word = 0;

for(bit_num = 0; bit_num < 16; bit_num++)
{
	test_word |= (1 << bit_num);			// Set bit - OK
}

test_word = 0xffff;

for(bit_num = 0; bit_num < 16; bit_num++)
{
	test_word &= ~(1 << bit_num);			// Clear bit - Only works up to 8 bits
}		

test_word = 0xffff;

for(bit_num = 0; bit_num < 16; bit_num++)
{
	x = test_word & (1 << bit_num);			// Test bit - Only works up to 8 bits
}

test_word = 0;

for(bit_num = 0; bit_num < 16; bit_num++)
{
	test_word ^= (1 << bit_num);			// Toggle bit 0 > 1 - OK
}

test_word = 0xffff;

for(bit_num = 0; bit_num < 16; bit_num++)
{
	test_word ^= (1 << bit_num);			// Toggle bit 1 > 0 - OK
}

// Workaround using intermediate variable

test_word = 0xffff;

for(bit_num = 0; bit_num < 16; bit_num++)
{
	y = (1 << bit_num);
	test_word &= ~y;				// Clear bit - Now OK
}

test_word = 0xffff;

for(bit_num = 0; bit_num < 16; bit_num++)
{
	y = (1 << bit_num);
	x = test_word & y;				// Clear bit - Now OK
}		
}

 

Comments:

 

Reproducible: 100%

 

IDE: V6.81

COMPILER: BoostC (using aggressive optimisation)

TARGET: 16F877

OS: XP PRO SP2

 

Thanks

 

DavidB

Share this post


Link to post
Share on other sites
Hi,

 

Bug Description:

 

The clear_bit(var,num) and test_bit(var,num) macros fail if the var is larger than 8 bits and num is a variable. The set_bit and toggle_bit macros appear to work as expected. The macros were expanded into standard code to prove the point as shown in the following snippet.

If an intermediate variable is used then the code for testing a bit and clearing a bit will compile and work as expected as shown in the last two examples.

I haven't fully checked but I believe the all macros are OK if num is a constant (also optimises code as well).

 

Expected Behaviour:

 

Not sure if this is a bug or just the way it works but I would expect to be able to use the standard bit shift method with any length of variable no matter how large the generated code. If there is a limit I would also expect a warning.

 

while(1)																// Loop forever
{
unsigned short test_word;				// Test word
unsigned short x;					// Test bit result
unsigned short y;					// Temporary variable							
unsigned char bit_num;				// Bit number

test_word = 0;

for(bit_num = 0; bit_num < 16; bit_num++)
{
	test_word |= (1 << bit_num);			// Set bit - OK
}

test_word = 0xffff;

for(bit_num = 0; bit_num < 16; bit_num++)
{
	test_word &= ~(1 << bit_num);			// Clear bit - Only works up to 8 bits
}		

test_word = 0xffff;

for(bit_num = 0; bit_num < 16; bit_num++)
{
	x = test_word & (1 << bit_num);			// Test bit - Only works up to 8 bits
}

test_word = 0;

for(bit_num = 0; bit_num < 16; bit_num++)
{
	test_word ^= (1 << bit_num);			// Toggle bit 0 > 1 - OK
}

test_word = 0xffff;

for(bit_num = 0; bit_num < 16; bit_num++)
{
	test_word ^= (1 << bit_num);			// Toggle bit 1 > 0 - OK
}

// Workaround using intermediate variable

test_word = 0xffff;

for(bit_num = 0; bit_num < 16; bit_num++)
{
	y = (1 << bit_num);
	test_word &= ~y;				// Clear bit - Now OK
}

test_word = 0xffff;

for(bit_num = 0; bit_num < 16; bit_num++)
{
	y = (1 << bit_num);
	x = test_word & y;				// Clear bit - Now OK
}		
}

 

Comments:

 

Reproducible: 100%

 

IDE: V6.81

COMPILER: BoostC (using aggressive optimisation)

TARGET: 16F877

OS: XP PRO SP2

 

Thanks

 

DavidB

Yes some of these cases do seem to be a problem.

Regards

Dave

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...