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 support@ccsinfo.com

Pointer Warning without Clear Reason

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



Joined: 27 Sep 2005
Posts: 25

View user's profile Send private message

Pointer Warning without Clear Reason
PostPosted: Thu May 12, 2016 3:39 pm     Reply with quote

I just started using 5.058 and am getting Warning#240 like others have mentioned. I have no problem with ignoring the warnings, or disabling them, but only after I fully understand the reason for such a warning and can convince myself that it is indeed not an issue.

Code:

// Compiled with CCS v5.058 with MPLABX IDE
#include <24FJ256GB106.h>   
#use delay(clock=32000000,crystal=8000000)

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

// Function skeletons
void    lcdDataWrite(char data[128]);

void main()
{
    char    dispBuffer[17];

    while(TRUE)
    {
        delay_ms(300);
        strcpy(dispBuffer, " FAULT (Up/Dn)  ");
        lcdDataWrite(dispBuffer);                      // <- Warning#240  Pointer types do not match
    }
}

void   lcdDataWrite(char data[128])
{
    unsigned int8   length;

    length = strlen(data);
    if (length > 16) {
        strncpy (data, data, 16);
    }
    //writenI2C(LCD_WR_ADDRESS, 0x40, length, data);
    return;
}


The function skeleton, the function call and the function all appear to match. What am I missing?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu May 12, 2016 4:11 pm     Reply with quote

It doesn't like the sized array as a parameter. I never do this, or rarely.
Other compilers will take this without issuing a warning. I don't use the
sized array syntax. I pass a char * pointer as the parameter.

In this stackoverflow thread, they say passing a sized array is bad.
They say Ritchie doesn't want you to do it. etc.
http://stackoverflow.com/questions/5187224/why-should-i-declare-a-c-array-parameters-size-in-a-function-header
Maybe that's why CCS decided to give a warning.
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

Re: Pointer Warning without Clear Reason
PostPosted: Fri May 13, 2016 6:25 pm     Reply with quote

Isn't it due to the fact that the pointers point to different sized arrays? Why not make everything char [17]? Wouldn't that fix it?
_________________
Robert Scott
Real-Time Specialties
Embedded Systems Consulting
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat May 14, 2016 12:29 am     Reply with quote

No, changing them all to 17 does not fix it. I thought of that and tested it
yesterday. It still gives the error:
Quote:

>>> Warning 240 "PCH_Test.c" Line 14(17,27): Pointer types do not match


Simplified test program, without all the string functions and includes
which are not needed to show the problem:
Code:
#include <18F46K22.h>
#fuses INTRC_IO, NOWDT
#use delay(clock=4M)

void  lcdDataWrite(char data[17]);

//====================================
void main()
{
char dispBuffer[17];

while(TRUE)
  {
   lcdDataWrite(dispBuffer); // <- Warning: Pointer types do not match
  }

}

//---------------------------------------
void   lcdDataWrite(char data[17])
{
unsigned int8   length;

length = 0x55;
}

This was tested with vs. 5.056.


Last edited by PCM programmer on Sat May 14, 2016 12:40 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Sat May 14, 2016 12:39 am     Reply with quote

No.

The point is that a 'pointer', is not actually an array. It can be used to access an array, but doesn't have the concept of a size associated with it.
When an array name is passed to a function, the array itself is not 'passed'.
Technically the 'array' is downgraded to a pointer. What is passed is the pointer, which has no 'knowledge' of how many elements it actually points to implicit in it.

I agree very wholeheartedly with the people in the Thread PCM_programmer linked to, who say that really it is better to be explicit here and have the function declaration saying that it is a pointer, and not an array.

The 'array', is a linear group of variables in memory. When you declare it, the memory is allocated for these, hence a 'size'. C has the convention, that the array 'name', is the address of these variables (so the pointer), and you can use a pointer to access data in an array. But you are not actually passing the array.

If you pass (say) an int16, the variable itself is copied and passed to the function. With an array, the array itself is _not_ passed. So what actually 'arrives' in the function, is not actually the array.....
SteveW



Joined: 27 Sep 2005
Posts: 25

View user's profile Send private message

PostPosted: Tue May 17, 2016 3:44 pm     Reply with quote

Thanks to all for your help. I thought that passing an array really passed an array, so that the size information was conveyed. The other compilers that I use don't complain, and "passing" arrays indeed always worked, so I never thought much about it until the latest CCS compilers started complaining.
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Wed May 18, 2016 12:37 am     Reply with quote

It is only a warning, but it is a fundamental 'thing' about C.

Many languages do pass arrays, or give you the choice (so in VB, the default is to pass 'by reference', but you have the option to pass 'by value'). However (of course) the latter brings a big cost in space and performance.
'By reference' passing is technically fractionally different from the pointer form in C, with you working directly 'with' the reference to the passed parameter.

There are actually four different 'forms'.

Pass by address. This is standard C. This is not 'by reference' passing, but merely passes the address of the target, which then depending on what you do, can be used to modify the original values.
Address with size. This is supported in ANSI C after C99, and here the array does not carry size information, but you are allowed to specify a size. The array is passed as a pointer, but the function can be specified with a size, which is then used for bounds checking if supported by the chip/compiler. Great where there is hardware bounds checking in the chip. This uses the 'static' keyword in C99.
By value passing (several languages support this), but very processor intensive - lots of work..... C does not support this
By reference passing. Here you change the actual variable in the calling program. Not originally supported in C, but present in C++, and now for limited types in CCS C.

Many languages do have an 'array' as a fundamental 'type'. So here the 'array' carries as part of itself, it's size information. C does not have this.

It is both incredibly powerful, and potentially dangerous (makes it easy to have functions modify the wrong address in memory, but allows very fast and easy movement of data). Adding 'warnings' is quite sensible to point out the potential dangers.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed May 18, 2016 1:45 am     Reply with quote

SteveW wrote:
I thought that passing an array really passed an array, so that the size information was conveyed.


As Ttelmah points outs C does not allow passing of entire arrays, only pointers to the variables in arays. He also points out that there is no concept of an array type in C. I want emphasise that that means there is no size to be passed, at least at runtime. Only the compiler knows how big an array is, or how many elements there are. That information is not available to running code, and has to be provided explicitly by the programmer.

That is not the case in C++ or C# and the like, where such information is encoded in to the structure and overhead of arrays. In C, at runtime, arrays don't have any overhead (well, in PIC Cs they often do to help overcome limitations of the processor hardware architecture). C arrays are simply and only a fixed number of elements.

sizeof() gives the number of bytes in a variable, whether a simple varaible, an array, a structure or whatever. It is information available to the compiler at compile time, and made available as constants at runtime. There can be no variable sized arrays in C. They ae fixed. They can be emulated using dynamic memory and pointers, but for embedded code, and very much so on PICs, that's deprecated as not being industry best practice.

As sizeof gives the size of a variable in bytes, to get the number of elements in an array you'd need to do sizeof the whole array divided by sizeof each element, i.e. sizeof(arrayname)/sizeof(arrayname[0]). This will not work in a routine where the array is passed as a parameter. Why? Because the size of the array is not available at runtime, and what is passed as a parameter is only known at runtime.

The C approach is very light on memory and makes parameter passing simple and efficient. It also places a lot more responsibility on the programmer as array bounds checking is not automatic and pointers can be misused.
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