Unknown Identifier while debugging

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hopefully someone can help me. I’m working on a program using Atmel Studio, ICE and Debug wire running on an Arduino. (And hopefully this is the correct forum for this question. If not let me know and I’ll re-post it in the correct one.)

 

If I stop at a breakpoint in a C++ class and attempt to look at a member variable, instead of the value of the variable I see “Unknown Identifier”. I have the variable declared volatile and the optimization level set to None (-O0). Looking at the disassembled code, it looks like my member variable is being stored on the stack (not 100% sure of this however, might be in some other register).

 

I did look through past posts looking for an answer and didn’t see anything recent, so I’m hoping this issue has been fixed.

 

Anyway, anyone know how to get around this issue so I can actually watch variables?

 

Attached as a snippet of test code to illustrate this issue.

 

Thanks,

 

Jack

Attachment(s): 

Jack

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That often happens to me when I try to inspect a C variable that is out of scope. Happens other times, also, as in a variable that is optimized away. For example, 

 

uint8_t x = MyFunction();
if ( x == 0 ) {
    ...
}

Which appears to be implemented as 

if ( MyFunction() == 0 ) {
    ...
}

In this case, if I try to inspect x, it is "unknown identifier".

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Wed. May 22, 2019 - 01:35 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Jim,

Thanks for the response. The variable is in scope when I look at it because I have a breakpoint in the get and set member functions. I'm sure the issue is that the variable is optimized into never-never land. The thing that bothers me is that I have that variable set to volatile, which should prevent the variable from being optimized away.

I am hoping that someone has a workaround to allow me to view that variable from the debugger.

Jack

Jack

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Perhaps you are trying to watch Num instead of A.Num (in setup()) or this->Num or just this in (class Foo member functions).

Last Edited: Wed. May 22, 2019 - 05:28 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


I don't do Arduino in AS7 but I simply built this:

class Foo
{
	private:
	volatile int Num = 0;

	public:
	int getNum()
	{
		return Num;  // <--- "Num" Unknown Identifier
	}

	void setNum(int i)
	{
		Num = i + 3;	// <--- "Num" Unknown Identifier
	}
};



void setup()
{
	// put your setup code here, to run once:
	Foo A;
	int x = 0;

	A.setNum(5);
	x = x + 5;

	x = A.getNum();
	int y = A.getNum() + 5;

}

int main(void) {
	setup();
}

and it generates:

0000006c <_Z5setupv>:
};



void setup()
{
  6c:	08 95       	ret

0000006e <main>:
	int y = A.getNum() + 5;

}

int main(void) {
	setup();
  6e:	0e 94 36 00 	call	0x6c	; 0x6c <_Z5setupv>
  72:	80 e0       	ldi	r24, 0x00	; 0
  74:	90 e0       	ldi	r25, 0x00	; 0
  76:	08 95       	ret

Just because the member is volatile does NOT mean it's going to be accessed. The problem here is not the volatility of "Num" but the (lack of) volatility of ""x" and "y". The compiler can see that x/y is never used so there's no point creating them.

 

When I use:

	// put your setup code here, to run once:
	Foo A;
	volatile int x = 0;

	A.setNum(5);
	x = x + 5;

	x = A.getNum();
	volatile int y = A.getNum() + 5;

then the code is:

0000006c <_Z5setupv>:
};



void setup()
{
  6c:	cf 93       	push	r28
  6e:	df 93       	push	r29
  70:	00 d0       	rcall	.+0      	; 0x72 <_Z5setupv+0x6>
  72:	00 d0       	rcall	.+0      	; 0x74 <_Z5setupv+0x8>
  74:	cd b7       	in	r28, 0x3d	; 61
  76:	de b7       	in	r29, 0x3e	; 62
	// put your setup code here, to run once:
	Foo A;
	volatile int x = 0;
  78:	1a 82       	std	Y+2, r1	; 0x02
  7a:	19 82       	std	Y+1, r1	; 0x01

	A.setNum(5);
	x = x + 5;
  7c:	89 81       	ldd	r24, Y+1	; 0x01
  7e:	9a 81       	ldd	r25, Y+2	; 0x02
  80:	05 96       	adiw	r24, 0x05	; 5
  82:	9a 83       	std	Y+2, r25	; 0x02
  84:	89 83       	std	Y+1, r24	; 0x01

	x = A.getNum();
  86:	88 e0       	ldi	r24, 0x08	; 8
  88:	90 e0       	ldi	r25, 0x00	; 0
  8a:	9a 83       	std	Y+2, r25	; 0x02
  8c:	89 83       	std	Y+1, r24	; 0x01
	volatile int y = A.getNum() + 5;
  8e:	8d e0       	ldi	r24, 0x0D	; 13
  90:	90 e0       	ldi	r25, 0x00	; 0
  92:	9c 83       	std	Y+4, r25	; 0x04
  94:	8b 83       	std	Y+3, r24	; 0x03

}
  96:	0f 90       	pop	r0
  98:	0f 90       	pop	r0
  9a:	0f 90       	pop	r0
  9c:	0f 90       	pop	r0
  9e:	df 91       	pop	r29
  a0:	cf 91       	pop	r28
  a2:	08 95       	ret

000000a4 <main>:

int main(void) {
	setup();
  a4:	0e 94 36 00 	call	0x6c	; 0x6c <_Z5setupv>
  a8:	80 e0       	ldi	r24, 0x00	; 0
  aa:	90 e0       	ldi	r25, 0x00	; 0
  ac:	08 95       	ret

So now setup() has some body to it. However the compiler (I use "Debug" which is -O1) is STILL too clever when it comes to optimising. It can see that "Num" is just 5 so it just hard codes the 5. The temptation would be to make "Foo A;" volatile too but that then leads to all kinds of other errors:

		.././main.cpp: In function 'void setup()':
C:\Users\uid23021\OneDrive - Continental AG\Documents\Atmel Studio\7.0\test_cpp\main.cpp(26,12): error: passing 'volatile Foo' as 'this' argument discards qualifiers [-fpermissive]
		  A.setNum(5);
		            ^

I don't know an easy way to correct this apart from doing as it suggests and invoking -fpermissive. However that STILL does not do it:

void setup()
{
  6c:	cf 93       	push	r28
  6e:	df 93       	push	r29
  70:	00 d0       	rcall	.+0      	; 0x72 <_Z5setupv+0x6>
  72:	00 d0       	rcall	.+0      	; 0x74 <_Z5setupv+0x8>
  74:	00 d0       	rcall	.+0      	; 0x76 <_Z5setupv+0xa>
  76:	cd b7       	in	r28, 0x3d	; 61
  78:	de b7       	in	r29, 0x3e	; 62
	// put your setup code here, to run once:
	volatile Foo A;
  7a:	1a 82       	std	Y+2, r1	; 0x02
  7c:	19 82       	std	Y+1, r1	; 0x01
	volatile int x = 0;
  7e:	1c 82       	std	Y+4, r1	; 0x04
  80:	1b 82       	std	Y+3, r1	; 0x03
		return Num;  // <--- "Num" Unknown Identifier
	}

	void setNum(int i)
	{
		Num = i + 3;	// <--- "Num" Unknown Identifier
  82:	88 e0       	ldi	r24, 0x08	; 8
  84:	90 e0       	ldi	r25, 0x00	; 0
  86:	9a 83       	std	Y+2, r25	; 0x02
  88:	89 83       	std	Y+1, r24	; 0x01
	// put your setup code here, to run once:
	volatile Foo A;
	volatile int x = 0;

	A.setNum(5);
	x = x + 5;
  8a:	8b 81       	ldd	r24, Y+3	; 0x03
  8c:	9c 81       	ldd	r25, Y+4	; 0x04
  8e:	05 96       	adiw	r24, 0x05	; 5
  90:	9c 83       	std	Y+4, r25	; 0x04
  92:	8b 83       	std	Y+3, r24	; 0x03
	volatile int Num = 0;

	public:
	int getNum()
	{
		return Num;  // <--- "Num" Unknown Identifier
  94:	89 81       	ldd	r24, Y+1	; 0x01
  96:	9a 81       	ldd	r25, Y+2	; 0x02
	volatile int x = 0;

	A.setNum(5);
	x = x + 5;

	x = A.getNum();
  98:	9c 83       	std	Y+4, r25	; 0x04
  9a:	8b 83       	std	Y+3, r24	; 0x03
	volatile int Num = 0;

	public:
	int getNum()
	{
		return Num;  // <--- "Num" Unknown Identifier
  9c:	89 81       	ldd	r24, Y+1	; 0x01
  9e:	9a 81       	ldd	r25, Y+2	; 0x02

	A.setNum(5);
	x = x + 5;

	x = A.getNum();
	volatile int y = A.getNum() + 5;
  a0:	05 96       	adiw	r24, 0x05	; 5
  a2:	9e 83       	std	Y+6, r25	; 0x06
  a4:	8d 83       	std	Y+5, r24	; 0x05

}
  a6:	26 96       	adiw	r28, 0x06	; 6
  a8:	0f b6       	in	r0, 0x3f	; 63
  aa:	f8 94       	cli
  ac:	de bf       	out	0x3e, r29	; 62
  ae:	0f be       	out	0x3f, r0	; 63
  b0:	cd bf       	out	0x3d, r28	; 61
  b2:	df 91       	pop	r29
  b4:	cf 91       	pop	r28
  b6:	08 95       	ret

I think you may have to accept that this example is just too trivial that you cannot get it to generate the setter/accessor code you are looking for. When you start to write real code that actually does something you will see the compiler generate something that is more easily debuggable.

 

EDIT: actually I find that if I give in and resort to -O0 (never a good idea at any time!!) then I can get setter/getter code:

0000006c <_ZN3Foo6getNumEv>:
{
	private:
	volatile int Num = 0;

	public:
	int getNum()
  6c:	cf 93       	push	r28
  6e:	df 93       	push	r29
  70:	00 d0       	rcall	.+0      	; 0x72 <_ZN3Foo6getNumEv+0x6>
  72:	cd b7       	in	r28, 0x3d	; 61
  74:	de b7       	in	r29, 0x3e	; 62
  76:	9a 83       	std	Y+2, r25	; 0x02
  78:	89 83       	std	Y+1, r24	; 0x01
	{
		return Num;  // <--- "Num" Unknown Identifier
  7a:	89 81       	ldd	r24, Y+1	; 0x01
  7c:	9a 81       	ldd	r25, Y+2	; 0x02
  7e:	fc 01       	movw	r30, r24
  80:	80 81       	ld	r24, Z
  82:	91 81       	ldd	r25, Z+1	; 0x01
	}
  84:	0f 90       	pop	r0
  86:	0f 90       	pop	r0
  88:	df 91       	pop	r29
  8a:	cf 91       	pop	r28
  8c:	08 95       	ret

0000008e <_ZN3Foo6setNumEi>:

	void setNum(int i)
  8e:	cf 93       	push	r28
  90:	df 93       	push	r29
  92:	00 d0       	rcall	.+0      	; 0x94 <_ZN3Foo6setNumEi+0x6>
  94:	00 d0       	rcall	.+0      	; 0x96 <_ZN3Foo6setNumEi+0x8>
  96:	cd b7       	in	r28, 0x3d	; 61
  98:	de b7       	in	r29, 0x3e	; 62
  9a:	9a 83       	std	Y+2, r25	; 0x02
  9c:	89 83       	std	Y+1, r24	; 0x01
  9e:	7c 83       	std	Y+4, r23	; 0x04
  a0:	6b 83       	std	Y+3, r22	; 0x03
	{
		Num = i + 3;	// <--- "Num" Unknown Identifier
  a2:	8b 81       	ldd	r24, Y+3	; 0x03
  a4:	9c 81       	ldd	r25, Y+4	; 0x04
  a6:	9c 01       	movw	r18, r24
  a8:	2d 5f       	subi	r18, 0xFD	; 253
  aa:	3f 4f       	sbci	r19, 0xFF	; 255
  ac:	89 81       	ldd	r24, Y+1	; 0x01
  ae:	9a 81       	ldd	r25, Y+2	; 0x02
  b0:	fc 01       	movw	r30, r24
  b2:	31 83       	std	Z+1, r19	; 0x01
  b4:	20 83       	st	Z, r18
	}
  b6:	00 00       	nop
  b8:	0f 90       	pop	r0
  ba:	0f 90       	pop	r0
  bc:	0f 90       	pop	r0
  be:	0f 90       	pop	r0
  c0:	df 91       	pop	r29
  c2:	cf 91       	pop	r28
  c4:	08 95       	ret

000000c6 <_Z5setupv>:
};



void setup()
{
  c6:	cf 93       	push	r28
  c8:	df 93       	push	r29
  ca:	00 d0       	rcall	.+0      	; 0xcc <_Z5setupv+0x6>
  cc:	00 d0       	rcall	.+0      	; 0xce <_Z5setupv+0x8>
  ce:	00 d0       	rcall	.+0      	; 0xd0 <_Z5setupv+0xa>
  d0:	cd b7       	in	r28, 0x3d	; 61
  d2:	de b7       	in	r29, 0x3e	; 62
	// put your setup code here, to run once:
	Foo A;
  d4:	1a 82       	std	Y+2, r1	; 0x02
  d6:	19 82       	std	Y+1, r1	; 0x01
	volatile int x = 0;
  d8:	1c 82       	std	Y+4, r1	; 0x04
  da:	1b 82       	std	Y+3, r1	; 0x03

	A.setNum(5);
  dc:	65 e0       	ldi	r22, 0x05	; 5
  de:	70 e0       	ldi	r23, 0x00	; 0
  e0:	ce 01       	movw	r24, r28
  e2:	01 96       	adiw	r24, 0x01	; 1
  e4:	0e 94 47 00 	call	0x8e	; 0x8e <_ZN3Foo6setNumEi>
	x = x + 5;
  e8:	8b 81       	ldd	r24, Y+3	; 0x03
  ea:	9c 81       	ldd	r25, Y+4	; 0x04
  ec:	05 96       	adiw	r24, 0x05	; 5
  ee:	9c 83       	std	Y+4, r25	; 0x04
  f0:	8b 83       	std	Y+3, r24	; 0x03

	x = A.getNum();
  f2:	ce 01       	movw	r24, r28
  f4:	01 96       	adiw	r24, 0x01	; 1
  f6:	0e 94 36 00 	call	0x6c	; 0x6c <_ZN3Foo6getNumEv>
  fa:	9c 83       	std	Y+4, r25	; 0x04
  fc:	8b 83       	std	Y+3, r24	; 0x03
	volatile int y = A.getNum() + 5;
  fe:	ce 01       	movw	r24, r28
 100:	01 96       	adiw	r24, 0x01	; 1
 102:	0e 94 36 00 	call	0x6c	; 0x6c <_ZN3Foo6getNumEv>
 106:	05 96       	adiw	r24, 0x05	; 5
 108:	9e 83       	std	Y+6, r25	; 0x06
 10a:	8d 83       	std	Y+5, r24	; 0x05

}
 10c:	00 00       	nop
 10e:	26 96       	adiw	r28, 0x06	; 6
 110:	0f b6       	in	r0, 0x3f	; 63
 112:	f8 94       	cli
 114:	de bf       	out	0x3e, r29	; 62
 116:	0f be       	out	0x3f, r0	; 63
 118:	cd bf       	out	0x3d, r28	; 61
 11a:	df 91       	pop	r29
 11c:	cf 91       	pop	r28
 11e:	08 95       	ret

00000120 <main>:

int main(void) {
 120:	cf 93       	push	r28
 122:	df 93       	push	r29
 124:	cd b7       	in	r28, 0x3d	; 61
 126:	de b7       	in	r29, 0x3e	; 62
	setup();
 128:	0e 94 63 00 	call	0xc6	; 0xc6 <_Z5setupv>
 12c:	80 e0       	ldi	r24, 0x00	; 0
 12e:	90 e0       	ldi	r25, 0x00	; 0
 130:	df 91       	pop	r29
 132:	cf 91       	pop	r28
 134:	08 95       	ret

But, really, if you want to learn C++ (not AVRs) you are better doing all this in a PC environment and using a PC compiler.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi MarekJ71

 

Thank you for your reply.

 

 I set a breakpoint in the class member function and that’s where I’m expecting to see the contents of Num. In fact, I built the exact same program as a C++ console app in Visual Studio (minus the Arduino stuff of course) and it worked as expected (I was able to see the contents of Num at the breakpoint in the member function).

 

Jack

Jack

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Clawson,

 

Thank you for your reply.

 

Yes that’s a simple illustration. I’m actually working on a larger app and what I posted was built as a simple test to try to isolate the issue. I probably should have left the ‘x’ and ‘y’ stuff out as that confuses the issue. I added it in an attempt to force the compiler to actually save Num to memory rather than the stack or to a register.

 

It seems to be a bug in the compiler that it optimizes when optimization is supposedly turned off. It’s been a long time written any assembler code so I guess I’ll have to bite the bullet and try to figure out what it’s doing “inside”.

 

In fact, I built the exact same program as a C++ console app in Visual Studio (minus the Arduino stuff of course) and it worked as expected (I was able to see the contents of Num at the breakpoint in the member function).

 

You say that -O0 is never a good idea at any time.  Why?

 

Also, in the project’s Toolchain -> compiler -> Debugger there are levels G1, G2, and G3. I can’t find any documentation as to what they do. Do you know?

 

Thanks again for your reply.

 

Jack

Jack

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JTGartner wrote:
You say that -O0 is never a good idea at any time.  Why?
If you've looked at the generated code you will already know why but note that anything that requires compact/fast code (such as some sequences that must complete in 4 cycles) just can't be achieved when built as -O0.

 

The -G1 etc are ELF (or rather DWARF) levels. It's basically "how much help do you want to give the debugger". I'd probably use level 3.

 

Your best bet is to study the LSS as I did above (I did that deliberately to illustrate the technique) in which case you can see whether code for the class methods is even being generated. Also even if the debugger won't admit to where this is pointing it should be obvious from the code.

 

While it must be written down somewhere it's clear that the C++ ABI is such that "this" is passed in R25:R24. In fact if I enable -save-temps, also -fverbose-asm and then set a post-build event to run my avr-source utility on the .s files I find the code generated is:

	.text
.Ltext0:

	.section	.text._ZN3Foo6getNumEv,"axG",@progbits,_ZN3Foo6getNumEv,comdat
	.weak	_ZN3Foo6getNumEv
	.type	_ZN3Foo6getNumEv, @function
_ZN3Foo6getNumEv:
//==> 	int getNum()
	push r28	 ; 
	push r29	 ; 
	 ; SP -= 2	 ; 
	rcall .
	in r28,__SP_L__	 ; 
	in r29,__SP_H__	 ; 
/* prologue: function */
/* frame size = 2 */
/* stack size = 4 */
.L__stack_usage = 4
	std Y+2,r25	 ;  this, this
	std Y+1,r24	 ;  this, this
//==> 		return Num;  // <--- "Num" Unknown Identifier
	ldd r24,Y+1	 ;  tmp44, this
	ldd r25,Y+2	 ;  tmp44, this
	movw r30,r24	 ; , tmp44
	ld r24,Z	 ;  D.1891, this_2(D)->Num
	ldd r25,Z+1	 ;  D.1891, this_2(D)->Num
/* epilogue start */
//==> 	}
	 ; SP += 2	 ; 
	pop __tmp_reg__
	pop __tmp_reg__
	pop r29	 ; 
	pop r28	 ; 
	ret
	.size	_ZN3Foo6getNumEv, .-_ZN3Foo6getNumEv

	.section	.text._ZN3Foo6setNumEi,"axG",@progbits,_ZN3Foo6setNumEi,comdat
	.weak	_ZN3Foo6setNumEi
	.type	_ZN3Foo6setNumEi, @function
_ZN3Foo6setNumEi:
//==> 	void setNum(int i)
	push r28	 ; 
	push r29	 ; 
	 ; SP -= 4	 ; 
	rcall .
	rcall .
	in r28,__SP_L__	 ; 
	in r29,__SP_H__	 ; 
/* prologue: function */
/* frame size = 4 */
/* stack size = 6 */
.L__stack_usage = 6
	std Y+2,r25	 ;  this, this
	std Y+1,r24	 ;  this, this
	std Y+4,r23	 ;  i, i
	std Y+3,r22	 ;  i, i
//==> 		Num = i + 3;	// <--- "Num" Unknown Identifier
	ldd r24,Y+3	 ;  tmp43, i
	ldd r25,Y+4	 ;  tmp43, i
	movw r18,r24	 ;  D.1892, tmp43
	subi r18,-3	 ;  D.1892,
	sbci r19,-1	 ;  D.1892,
	ldd r24,Y+1	 ;  tmp44, this
	ldd r25,Y+2	 ;  tmp44, this
	movw r30,r24	 ; , tmp44
	std Z+1,r19	 ;  this_4(D)->Num, D.1892
	st Z,r18	 ;  this_4(D)->Num, D.1892
//==> 	}
	nop
/* epilogue start */
	 ; SP += 4	 ; 
	pop __tmp_reg__
	pop __tmp_reg__
	pop __tmp_reg__
	pop __tmp_reg__
	pop r29	 ; 
	pop r28	 ; 
	ret
	.size	_ZN3Foo6setNumEi, .-_ZN3Foo6setNumEi

	.section	.text._Z5setupv,"ax",@progbits
.global	_Z5setupv
	.type	_Z5setupv, @function
_Z5setupv:
//==> {
	push r28	 ; 
	push r29	 ; 
	 ; SP -= 6	 ; 
	rcall .
	rcall .
	rcall .
	in r28,__SP_L__	 ; 
	in r29,__SP_H__	 ; 
/* prologue: function */
/* frame size = 6 */
/* stack size = 8 */
.L__stack_usage = 8
//==> 	Foo A;
	std Y+2,__zero_reg__	 ;  A.Num,
	std Y+1,__zero_reg__	 ;  A.Num,
//==> 	volatile int x = 0;
	std Y+4,__zero_reg__	 ;  x,
	std Y+3,__zero_reg__	 ;  x,
//==> 	A.setNum(5);
	ldi r22,lo8(5)	 ; ,
	ldi r23,0	 ; 
	movw r24,r28	 ;  tmp47,
	adiw r24,1	 ;  tmp47,
	call _ZN3Foo6setNumEi	 ; 
//==> 	x = x + 5;
	ldd r24,Y+3	 ;  D.1893, x
	ldd r25,Y+4	 ;  D.1893, x
	adiw r24,5	 ;  D.1893,
	std Y+4,r25	 ;  x, D.1893
	std Y+3,r24	 ;  x, D.1893
//==> 	x = A.getNum();
	movw r24,r28	 ;  tmp48,
	adiw r24,1	 ;  tmp48,
	call _ZN3Foo6getNumEv	 ; 
	std Y+4,r25	 ;  x, D.1893
	std Y+3,r24	 ;  x, D.1893
//==> 	volatile int y = A.getNum() + 5;
	movw r24,r28	 ;  tmp49,
	adiw r24,1	 ;  tmp49,
	call _ZN3Foo6getNumEv	 ; 
	adiw r24,5	 ;  D.1893,
	std Y+6,r25	 ;  y, D.1893
	std Y+5,r24	 ;  y, D.1893
//==> }
	nop
/* epilogue start */
	adiw r28,6	 ; ,
	in __tmp_reg__,__SREG__
	cli
	out __SP_H__,r29	 ; ,
	out __SREG__,__tmp_reg__
	out __SP_L__,r28	 ; ,
	pop r29	 ; 
	pop r28	 ; 
	ret
	.size	_Z5setupv, .-_Z5setupv

In which case it becomes fairly easy to see what is being stored where. The setup() for example creates 6 bytes on the stack frame from Y+1 to Y+6 then uses Y+1,Y+2 for the A.Num member and Y+3,Y+4 for 'x' and Y+5,Y+6 for 'y'

 

When it calls the setter/getter it clearly passes "this" (that is the address of A.Num as it's the only member) in R25:R24 and you can see the get/set accessing indirectly off this having moved it into Z.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks again for the reply clawson.

I'll have to dig into your reply in depth. Like I said in a previous response it's been a while since I've coded in assembler (30 plus years ago on a Motorola 68000). I wish this compiler didn't do such a "good job" optimizing so it would easier to debug.

Thanks again for your time replying to me.

Jack

Jack

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


On the whole I would expect you to be able to debug the (awful!) code if you stick with -O0. That was my experience with:

 

 

in fact built -O0 I very much doubt I needed "volatile"....

 

...quick check confirms this. I can see all the variables when built -O0 and without volatile...

 

 

All of A.Num, x, y have been set to expected values here and are fully watchable.

 

(but don't make the mistake of forgetting to undo the -O0 thing when you want some real micro-controller code!)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you, that's what I wanted to do. I didn't realize that you had to view member variable values from the level that (I assume) instantiated the class. I assumed that you could view them from within a class member function as in other IDE's (i.e., Visual Studio). A bit cumbersome, but it'll work.

 

You solved my problem - Thanks.

 

Jack

Jack

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This IDE is Visual Studio (Visual Studio 2015 in fact)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

>>> This IDE is Visual Studio (Visual Studio 2015 in fact)

 

 

Yes I know that. I guess what I was trying to say is that it behaves differently in this manner than other IDE's that I have used (including the MS version of Visual Studio that I currently use).

 

Jack

Jack