1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice
Ian Rogers

Are you needing to learn C!!!

compiling C sucsessfully

  1. Ian Rogers
    I'm doing this article as I keep telling folk C is dead easy to learn!!

    Well!! As I have heard from several members, not quite!!! It really never crossed my mind that after several minutes / hours typing in a program is thwarted by the error window... As I have evolved with C, so has my understanding of various errors that pop up.. I thought (wrongly) that the C errors were in line with assembly errors... Well they kinda are... It seems that C compiler developers speak a different language to the rest of us..

    A man named Tony Cunningham compiled a pretty good list here..

    http://www.netfunny.com/rhf/jokes/91q3/cerrors.html

    I think just to let wannabe C learners see that most of the errors are normal errors, but dressed up to sound "CRITICAL" so we are to just run and hide...

    I'm gong to run a couple of examples and show the errors that could be achieved by not complying with the ANSI code...

    Small C program
    Code (c):

    void main(void)
       {
       char x;

       RA4 = 0
       RA4 = 1;

       add(3,4);
       }

    int add(int x, int y)
       {
       return x+y;
       }
     
    Okay! I'm happy with that... Press compile..

    Build C:\Users\Ian Rogers\Documents\c code\Learning C\learnC for device 12F1840
    Using driver C:\Program Files (x86)\Microchip\xc8\v1.33\bin\xc8.exe

    Make: The target "C:\Users\Ian Rogers\Documents\c code\Learning C\learnC.p1" is out of date.
    Executing: "C:\Program Files (x86)\Microchip\xc8\v1.33\bin\xc8.exe" --pass1 "C:\Users\Ian Rogers\Documents\c code\Learning C\learnC.c" -q --chip=12F1840 -P --runtime=default --opt=default -N-1 -D__DEBUG=1 -g --asmlist "--errformat=Error [%n] %f; %l.%c %s" "--msgformat=Advisory[%n] %s" "--warnformat=Warning [%n] %f; %l.%c %s"
    Error [192] C:\Users\Ian Rogers\Documents\c code\Learning C\learnC.c; 6.1 undefined identifier "RA4"
    Error [195] C:\Users\Ian Rogers\Documents\c code\Learning C\learnC.c; 7.1 expression syntax
    Warning [361] C:\Users\Ian Rogers\Documents\c code\Learning C\learnC.c; 9.1 function declared implicit int
    Error [987] C:\Users\Ian Rogers\Documents\c code\Learning C\learnC.c; 15.1 arguments redeclared
    Error [1098] C:\Users\Ian Rogers\Documents\c code\Learning C\learnC.c; 15.1 conflicting declarations for variable "add" (C:\Users\Ian Rogers\Documents\c code\Learning C\learnC.c:14)
    (908) exit status = 1

    ********** Build failed! **********

    Whoooh!! Double dutch!!

    Okay start from the first error.. 192 undefined identifier "RA4" RA4 hasn't been defined.. This is the same error in assembly... we need to define RA4 to PORTA.4 we need to include the header just as we do in assembly Fortunately we only need to include the XC header.. this locates and includes the correct header file for us.. It's worth looking for this header and viewing the search path as it also includes built in functions..

    Error 195 expression syntax This covers a multitude of faults.. Mainly typo's.. In this case I have forgotten the semi colon that ends expressions.. The trouble is the error doesn't have to be on that line, as there is no semi colon on the previous line the parser continues until it finds one, only then throws an error..

    Error 987 arguments redeclared This is a bit of a pig as the declaration could be anywhere.. In this case the add(); function has already been used previously within the main... We would need to
    a) declare the function before the main or
    b) place main below the function....​

    Incidentally the warning 361 has already warned us that there is no declaration function declared implicit int I still don't understand why?? But as functions normally return an int ( unless otherwise stated ) that would make sense... This warning is always the same.. the compiler has not been told previously about the function so cannot determine call sizes.... Interestingly C has a different stack to assembled code... The mid sized pic16 has an 8 level stack... In C we have to remember all local variables all passing parameters and the functions return pointer.. normally C starts with 255 byte stack if there is room.. You can see why it isn't wise to use C on a tiny 56 byte 'o' ram micro!!

    Error 1098 is basically telling us that the first definition of the function add() looks nothing like the real version of the function add(), but we already know this..

    Correct the several errors
    Code (c):

    //include header for sfr's and such
    #include<xc.h>

    // moved to before main
    int add(int x, int y)
       {
       return x+y;
       }

    void main(void)
       {
       char x;

       RA4 = 0;   // repair typo
       RA4 = 1;

       add(3,4);
       }
     
    Clean build... One warning explaining that char x was declared by wasn't used...

    I'm going to find out by asking members of the forum what errors they want me to explain and get it on here..

    The error I seem to get the most is the implicit int error..
    Code (c):

    //include header for sfr's and such
    #include<xc.h>

    char buffer[10];

    void main(void)
       {
       int x;

       x = 3567;
       sprintf(buffer,"%d",x);
       }
     
    A valid statement... but sprintf() is declared in the stdio.h so we need to include it.
    this code throws up the warning, but then fails to compile with error 1098
    conflicting declarations for variable "_sprintf"

    We include stdio.h
    Code (c):

    #include<xc.h>
    #include<stdio.h>

    char buffer[10];  

    void main(void)
       {
       int x;

       x = 3567;
       sprintf(buffer,"%d",x);
       }
     
    But then you may see a warning about the variable "buffer" suspicious conversion..
    This warning doesn't even point you to any fault.. In fact most of the string functions use non ANSI routines to cover the two pointer types..

    sprintf is declared... int sprintf ( char * str, const char * format, ... );
    as you can see we have two types.. char* and const char*.. printf() although similar only has the const char*... Constant usually means code BUT!! as we all know a constant can be a variable... This is just one to watch... This warning can be suppressed in the options..

    Type conversion or the lack of it causes major heartache..
    Here we have pointers in our add() function..
    Code (c):

    //include header for sfr's and such
    #include<xc.h>

    int add(int* x, int* y)
       {
       return x+y;
       }

    void main(void)
       {
       int x, y, z;
     
       y = 30;
       x = 10;

       z = add(x,y);
       }
     
    There are more warnings than errors

    We have one warning 359 .. illegal conversion of pointer to integer
    and two others 358.. illegal conversion of integer to pointer

    Then the error 209.. Type conflict

    x and y are integer number variables add() expects the location of x and the location of y but receives the value of x and y...

    All because a pointer is an addressed variable... The compiler doesn't know if it is using the data x and y or the data stored at location x or y.. This in assembler would assemble but!!! the results would be far from correct!! When using C we have to tell the compiler exactly what we want the types to do what to operate on and what not to operate on..

    Code (c):

    int add(int* x, int* y)  // pointers..
       {
       return *x+*y;    //  pointed at..
       }

    void main(void)
       {
       int x, y, z;
     
       y = 30;
       x = 10;

       z = add(&x,&y);   // referenced variables
       }
     
    The only warning we get now is that we don't use z... We fill it, but then don't use it!


    I will expand this within the next few weeks....
    mdf, Willen, koolguy and 1 other person like this.