From: Robby on
Hello Giovanni,

Thankfully, this solves question #1.... I thankyou for this. With all the
porting and tests I have been doing I overlooked this.... I appologize.

However, question #2 behaves exactly as I described.... and I don't know why.

Do you see something I don't see?

Thanks!

--
Best regards
Roberto


"Giovanni Dicanio" wrote:

> "Robby" <Robby(a)discussions.microsoft.com> ha scritto nel messaggio
> news:DA43D6FB-193D-472F-90C8-3A424DA34A63(a)microsoft.com...
>
> > void innit_buff()
> > {
> > int i=0;
> > // RESET FLASH BUFFER
> > for(i=0; i<88; i++)
> > spiFLASH_BUFFER[88] = 97; // <<< buffer assignment!
>
> Should it be the following?
>
> spiFLASH_BUFFER[i] = 97;
>
> (instead of spiFLASH_BUFFER[88] = 97, which is also invalid buffer overrun
> if spiFLASH_BUFFER has 88 items; in fact, the last item index is N-1 = 88-1
> = 87).
>
> Giovanni
>
>
> .
>
From: Robby on
"Igor Tandetnik" wrote:

> Robby <Robby(a)discussions.microsoft.com> wrote:
> t i=0;
> > // RESET FLASH BUFFER
> > for(i=0; i<88; i++)
> > spiFLASH_BUFFER[88] = 97; // <<< buffer assignment!
>
> You are assigning the same value to the same element spiFLASH_BUFFER[88] mutliple times. Further, 88 is not a valid index into spiFLASH_BUFFER - you have a buffer overrun here. I'm pretty sure you meant spiFLASH_BUFFER[i]
>
> > unsigned char spiFLASH_BUFFER[88]; // extern declared in exactly one
> > .c file!
> >
> > void set_spi_flash_buffer(unsigned char spiFLASH_BUFFER[])
>
> By giving function parameter the same name as a global variable, you are confusing yourself.

Yeah, alot of other things have to still be changed! But yeah, Giovanni
pointed that [88] typo also. I don't know how that got there????

>
> > QUESTION #1:
> >
> > When the program hits BREAKPOINT #1, the "buffer assignment" line of
> > code (in setup.c) assigns to the buffer the value of 97.
>
> No it doesn't. It writes the value 97 88 times beyond the end of the buffer. The buffer itself remains unchanged.
>
> > QUESTION #2:
> >
> > When the program hits BREAKPOINT #2, the values of the
> > "spiFLASH_BUFFER[88]" char array are not even displayed anymore in
> > the watch window ??? All I see in the watch window now is a small
> > blue cube and 0 as its value, like this:
> >
> > spiFLASH_BUFFER 0x00e953c0
> > [] ....0
>
> Within set_spi_flash_buffer, spiFLASH_BUFFER refers to the function's parameter, not to the global variable. And since the parameter is declared without array size, the debugger doesn't know how many elements you expect it to display.

ah yes, hum! I don't know why the hell I was passing the array while it was
even declared global *and get this* it always worked in the other bloody old
compiler like as if all of this was normal ...... ooofff! I tel ya! porting
and adjusting to compiler compliance.... this won't be easy!

here's the code that outputs the correct info in the watch window.

=========================main.c
#include <stdio.h>
#include "setup.h"
#include "spi.h"

int main()
{
innit_buff();
set_buffer();
return 0;
}

=====================setup.h
#ifndef SETUP_H
#define SETUP_H

void innit_buff();

#endif // SETUP_H //

=====================setup.c
#include "setup.h"
#include "spi.h"

void innit_buff()
{

int i=0;

// RESET FLASH BUFFERS
for(i=0; i<88; i++)
spiFLASH_BUFFER[i] = 97;

}

=======================spi.h

#ifndef SPI_H
#define SPI_H

extern unsigned char spiFLASH_BUFFER[88];
void set_buffer();

#endif // SPI_H //

=======================spi.c
#include "spi.h"

unsigned char spiFLASH_BUFFER[88];

void set_buffer()
{
int r=0;
for(r=0;r<44;r++)
spiFLASH_BUFFER[r]= 0;

for(r=44;r<87;r++)
spiFLASH_BUFFER[r]= 255;

r = 0;

}
==========================

I made the changes in the real project, and the watch window displays
exactly what I was looking for.

Thankyou Igor.

On another note, Igor, those inclusion guards you showed me 2 weeks ago are
the best thing since sliced bread for me. I include exactly what I need for
every .c file and include within the inclusion guards the .h files that I
need and I don't get confused anymore. Its great!

However, sometimes in header files that others wrote, I sometimes see
multiple inclusion guards in the header files. This obviously tells me that
depending on another defined variable, we would allow different inclusions.
But why would people do this?

regards
Rob
From: Igor Tandetnik on
Robby <Robby(a)discussions.microsoft.com> wrote:
> "Igor Tandetnik" wrote:
>> Within set_spi_flash_buffer, spiFLASH_BUFFER refers to the
>> function's parameter, not to the global variable. And since the
>> parameter is declared without array size, the debugger doesn't know
>> how many elements you expect it to display.
>
> ah yes, hum! I don't know why the hell I was passing the array while
> it was even declared global *and get this* it always worked in the
> other bloody old compiler like as if all of this was normal ......

It works in VC, too. It is legal to name a parameter, or a local variable, the same as a global variable. It's just confusing - mainly to yourself, because you had this unreasonable expectation that the parameter _is_ the same as the global variable just because it has the same name. Consider:

char x = 'x';
char y = 'y';

void f(char x) {
// x here is unrelated to the global variable named x.
printf("%c\n", x);
}

int main() {
f(y); // prints "y"
return 0;
}

> unsigned char spiFLASH_BUFFER[88];
>
> void set_buffer()
> {
> int r=0;
> for(r=0;r<44;r++)
> spiFLASH_BUFFER[r]= 0;
>
> for(r=44;r<87;r++)
> spiFLASH_BUFFER[r]= 255;

Did you mean not to assign to spiFLASH_BUFFER[87]?

> However, sometimes in header files that others wrote, I sometimes see
> multiple inclusion guards in the header files. This obviously tells
> me that depending on another defined variable, we would allow
> different inclusions. But why would people do this?

#ifdef et al is not just use for include guards. It's a general purpose mechanism for conditional compilation. Include guards is just one particular application of this general technique:

http://en.wikipedia.org/wiki/C_preprocessor#Conditional_compilation

For example, imagine that you are trying to write code that would compile both on MSVC and on your other compiler where int is 8 bit. Suppose you need an integer type that is always 8 bit regardless of which compiler you are targeting. You can do this:

#if defined (MSVC)
typedef int int8;
#elif defined(MY_OTHER_COMPILER)
typedef signed char int8;
#else
#error Define the compiler you want to build for.
#endif

Now in your project settings (or makefiles, or whatever you use to drive the build) you can define an appropriate macro, and in your code just use int8 knowing that it will be defined appropriately.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925

From: Robby on
> It works in VC, too. It is legal to name a parameter, or a local variable,
the same as a global variable. It's just confusing - mainly to yourself,
because you had this unreasonable expectation that the parameter _is_ the
same as the global variable just because it has the same name. Consider:
>
> char x = 'x';
> char y = 'y';
>
> void f(char x) {
> // x here is unrelated to the global variable named x.
> printf("%c\n", x);
> }
>
> int main() {
> f(y); // prints "y"
> return 0;
> }

Okay!

> > unsigned char spiFLASH_BUFFER[88];
> >
> > void set_buffer()
> > {
> > int r=0;
> > for(r=0;r<44;r++)
> > spiFLASH_BUFFER[r]= 0;
> >
> > for(r=44;r<87;r++)
> > spiFLASH_BUFFER[r]= 255;
>
> Did you mean not to assign to spiFLASH_BUFFER[87]?
Come again! I don't understand your question!


> #ifdef et al is not just use for include guards. It's a general purpose mechanism for conditional compilation. Include guards is just one particular application of this general technique:
>
> http://en.wikipedia.org/wiki/C_preprocessor#Conditional_compilation
>
> For example, imagine that you are trying to write code that would compile both on MSVC and on your other compiler where int is 8 bit. Suppose you need an integer type that is always 8 bit regardless of which compiler you are targeting. You can do this:
>
> #if defined (MSVC)
> typedef int int8;
> #elif defined(MY_OTHER_COMPILER)
> typedef signed char int8;
> #else
> #error Define the compiler you want to build for.
> #endif
>
> Now in your project settings (or makefiles, or whatever you use to drive the build) you can define an appropriate macro, and in your code just use int8 knowing that it will be defined appropriately.

Understood!

Thanks Igor!
From: Igor Tandetnik on
Robby wrote:
>>> unsigned char spiFLASH_BUFFER[88];
>>>
>>> void set_buffer()
>>> {
>>> int r=0;
>>> for(r=0;r<44;r++)
>>> spiFLASH_BUFFER[r]= 0;
>>>
>>> for(r=44;r<87;r++)
>>> spiFLASH_BUFFER[r]= 255;
>>
>> Did you mean not to assign to spiFLASH_BUFFER[87]?
>
> Come again! I don't understand your question!

You have declared the array as spiFLASH_BUFFER[88], so valid indexes run from 0 through 87 inclusive. The function above assigns values to elements at indexes 0 through 86, but leaves spiFLASH_BUFFER[87] unchanged. I wondered whether you did it intentionally or accidentally.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925