CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PIC18F252, CCS-IDE 3.249, passing an array

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ulg



Joined: 09 May 2019
Posts: 24

View user's profile Send private message

PIC18F252, CCS-IDE 3.249, passing an array
PostPosted: Mon May 13, 2019 4:41 am     Reply with quote

I prefer to use 1st notation for passing an array, if I know the array's size, but this doesn't work in my actual program - I've to use the 2nd notation to get a working program, which overwrites tx[1] .. tx[3] when calling function ddOverWr(..).

I don't know, why?

1st notation:
Code:

.................... void ddOverWr(tDd* p, char dat[3]) {                          //[
....................     dat[0] = '|';
0E5C:  MOVLB  1
0E5E:  MOVFF  1CC,FE9
0E62:  MOVFF  1CD,FEA
0E66:  MOVLW  7C
0E68:  MOVWF  FEF
....................     dat[1] = '?';
0E6A:  MOVLW  01
0E6C:  ADDWF  xCC,W
0E6E:  MOVWF  FE9
0E70:  MOVLW  00
0E72:  ADDWFC xCD,W
0E74:  MOVWF  FEA
0E76:  MOVLW  3F
0E78:  MOVWF  FEF
....................     dat[2] = '?'; 
0E7A:  MOVLW  02
0E7C:  ADDWF  xCC,W
0E7E:  MOVWF  FE9
0E80:  MOVLW  00
0E82:  ADDWFC xCD,W
0E84:  MOVWF  FEA
0E86:  MOVLW  3F
0E88:  MOVWF  FEF
.................... }                                                             //]
0E8A:  MOVLB  0
0E8C:  GOTO   124A (RETURN)



....................               tx[1] = '@';
1222:  MOVLW  40
1224:  MOVWF  xCA
....................               tx[2] = '!';
1226:  MOVLW  21
1228:  MOVWF  xCB
....................               tx[3] = '@';
122A:  MOVLW  40
122C:  MOVWF  xCC
....................               ddOverWr(ddObjPtr(), &tx[1]);
122E:  RCALL  0D1A
1230:  MOVFF  02,1C9
1234:  MOVFF  01,1C8
1238:  MOVFF  02,1CB
123C:  MOVFF  01,1CA
1240:  MOVLW  CA
1242:  MOVLB  1
1244:  MOVWF  xCC
1246:  MOVLB  0
1248:  BRA    0E5C


2nd notation:
Code:

.................... void ddOverWr(tDd* p, char* dat) {                            //[
....................     dat[0] = '|';
0E5C:  MOVLB  1
0E5E:  MOVFF  1CC,FE9
0E62:  MOVFF  1CD,FEA
0E66:  MOVLW  7C
0E68:  MOVWF  FEF
....................     dat[1] = '?';
0E6A:  MOVLW  01
0E6C:  ADDWF  xCC,W
0E6E:  MOVWF  FE9
0E70:  MOVLW  00
0E72:  ADDWFC xCD,W
0E74:  MOVWF  FEA
0E76:  MOVLW  3F
0E78:  MOVWF  FEF
....................     dat[2] = '?'; 
0E7A:  MOVLW  02
0E7C:  ADDWF  xCC,W
0E7E:  MOVWF  FE9
0E80:  MOVLW  00
0E82:  ADDWFC xCD,W
0E84:  MOVWF  FEA
0E86:  MOVLW  3F
0E88:  MOVWF  FEF
.................... }                                                             //]
0E8A:  MOVLB  0
0E8C:  GOTO   124C (RETURN)


....................               tx[1] = '@';
1222:  MOVLW  40
1224:  MOVWF  xCA
....................               tx[2] = '!';
1226:  MOVLW  21
1228:  MOVWF  xCB
....................               tx[3] = '@';
122A:  MOVLW  40
122C:  MOVWF  xCC
....................               ddOverWr(ddObjPtr(), &tx[1]);
122E:  RCALL  0D1A
1230:  MOVFF  02,1C9
1234:  MOVFF  01,1C8
1238:  MOVFF  02,1CB
123C:  MOVFF  01,1CA
1240:  MOVLB  1
1242:  CLRF   xCD
1244:  MOVLW  CA
1246:  MOVWF  xCC
1248:  MOVLB  0
124A:  BRA    0E5C


Last edited by ulg on Mon May 13, 2019 8:09 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Mon May 13, 2019 7:46 am     Reply with quote

Your two code posts are identical.

However the key thing is that C does not have any concept of passing the
size of an array. In C if you want to pass the size, you have to do this as a
separate variable, containing the size. Passing a size, is an extension
added in later variant languages like C++, and not part of C.

An array is always passed as a pointer. Nothing else. Just says where
in memory it's first element is. Passing 'by value' is not supported. So
if you pass an array to a function and then modify an element, the
original array is changed.
ulg



Joined: 09 May 2019
Posts: 24

View user's profile Send private message

PostPosted: Mon May 13, 2019 8:14 am     Reply with quote

Sorry - I've made a mistake when copying 2nd version (copied from wrong file or ctrl-C hasn't worked) - I've corrected it.

The called function will be compiled to same code for both notations, but the calling code will differ. The second one works.

1240: MOVLW CA
1242: MOVLB 1
1244: MOVWF xCC
1246: MOVLB 0
1248: BRA 0E5C

vs

1240: MOVLB 1
1242: CLRF xCD
1244: MOVLW CA
1246: MOVWF xCC
1248: MOVLB 0
124A: BRA 0E5C
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Mon May 13, 2019 8:30 am     Reply with quote

Since the second one is the correct notation, it is not surprising....

As I said, C does not support passing an array with a size.

You can use:

void ddOverWr(tDd* p, char dat[]) {

or

void ddOverWr(tDd* p, char* dat) {
ulg



Joined: 09 May 2019
Posts: 24

View user's profile Send private message

PostPosted: Mon May 13, 2019 9:15 am     Reply with quote

Of course I do not pass the size of an array with 1st notation, but I give a hint to the compiler to report any try to access elements above 2 to be an error - aside from this hint, both notations should be the same.

Therefore, when I add the line

dat[3] = '*';

to the called function, the program will be compiled without any error with 2nd notation while the compiler reports an "subscript out of range" with 1st notation as CCS 3.249 does.
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Mon May 13, 2019 10:16 am     Reply with quote

The point is that passing a size, is _not legal_ in C. The first notation
is just 'wrong'. The idea of limit checking is not a feature in C. Arrays don't
have sizes. This has been added to many later languages, but is not part of
C. Hence it doesn't work.
ulg



Joined: 09 May 2019
Posts: 24

View user's profile Send private message

PostPosted: Mon May 13, 2019 11:25 am     Reply with quote

In my view all three notations

void ddOverWr(tDd* p, char dat[3])
void ddOverWr(tDd* p, char* dat)
void ddOverWr(tDd* p, char dat[])

are legal C, otherwise the compiler would report an error.

At all three notations the array parameter degrades to a pointer.

But only the first one offers the possibility to the compiler to report an error when accessing elements beyond element 2, if element number can be evaluated at compile time (e.g. with constant expressions), which CCS 3.249 does!

https://blog.feabhas.com/2013/11/shock-horror-i-learned-something-about-arrays-in-c/

Because the called function is compile to the same code for the first two notations (and I assume also for the third notation), my problem isn't located inside the called function, the problem arise on calling the function.
temtronic



Joined: 01 Jul 2010
Posts: 9241
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon May 13, 2019 11:32 am     Reply with quote

re:
are legal C, otherwise the compiler would report an error.

Maybe legal 'C' but not necessarily legal CCS 'C' ! There's probably 100+ variations of 'C' and NO version is 'cast in stone' as the ONE and ONLY version that must be used. K&R is the great,great grandfather though I believe even it 'evolved' over the years......
ulg



Joined: 09 May 2019
Posts: 24

View user's profile Send private message

PostPosted: Mon May 13, 2019 11:47 am     Reply with quote

It seems to be legal CCS 'C' too, because CCS 'C' doesn't report an error, when using "char dat[3]" notation - furthermore it uses the information given with the "3" to report a "subscript out of range" error, when I acccess e.g. dat[3] inside the called function (of course only when using "char dat[3]" notation).
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Mon May 13, 2019 2:04 pm     Reply with quote

No.

The reason it doesn't report an error, is that a size is both required and
legal, when using a multi-dimensional array. The compiler is not smart
enough to realise that the value here is not wanted.

It is actually an 'optional extension' in C99. But 3.249, is basically
pure K&R C, not C99.
It is not used as a size check declared as shown. Like this it is purely
for documentation (to tell the person reading the code how large the
array is expected to be). To be used as a size check, the keyword 'static'
has to be added.
However in both forms it is not part of CCS C.
ulg



Joined: 09 May 2019
Posts: 24

View user's profile Send private message

PostPosted: Tue May 14, 2019 3:43 am     Reply with quote

Ok - that is understandable

I have just identified the third, for me unusual behavior of the CCS compiler - it doesn't support assignments of structs (and doesn't report any errors) - I have to do component-wise copying of structs, otherwise my prgramm fails.

Code:

  //p->fifo[p->wrIdx] = *msg;
  p->fifo[p->wrIdx].typ = msg->typ;
  p->fifo[p->wrIdx].val = msg->val;



  //*msg = p->fifo[p->rdIdx];
  msg->typ = p->fifo[p->rdIdx].typ;
  msg->val = p->fifo[p->rdIdx].val;


It would be helpful to have a list of the pitfalls of that compiler - does anyone know, if something like this exists?
Ttelmah



Joined: 11 Mar 2010
Posts: 19538

View user's profile Send private message

PostPosted: Tue May 14, 2019 4:02 am     Reply with quote

Seriously, you are using a fourteen year old compiler version.
99.999% of your problems are from this.
There were historical issues with complex constructions such as references
inside references many years ago. It looks as if you are hitting this.
ulg



Joined: 09 May 2019
Posts: 24

View user's profile Send private message

PostPosted: Tue May 14, 2019 4:29 am     Reply with quote

I have to do some minor extension to a product developed in the years after 2002. To avoid complex testing of different software versions on different hardware versions for different customers, I refrain from porting this software to MPLAB X.
temtronic



Joined: 01 Jul 2010
Posts: 9241
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue May 14, 2019 5:14 am     Reply with quote

You don't need MPLAB X, you need a newer version of the CCS C Compiler. I use both PCM and PCH compilers 'through' MPLAB v8.92 to program PICs .Have done for 20+ years, starting with PCM v2.43. Over the years I've used 4.xxx and 5.0xx versions using MPLAB 8.92 and can program PICs just fine.


Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue May 14, 2019 11:41 am     Reply with quote

ulg wrote:

It would be helpful to have a list of the pitfalls of that compiler - does anyone know, if something like this exists?

Here is a list for PCH vs. 4.140, put together by a forum member in 2013:
http://www.ccsinfo.com/forum/viewtopic.php?t=50289
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group