1. This forum section is a read-only archive which contains old newsgroup posts. If you wish to post a query, please do so in one of our main forum sections (here). This way you will get a faster, better response from the members on Motherboard Point.

function call with arguments which takes no arguments

Discussion in 'Embedded' started by Neo, Jan 19, 2005.

  1. Neo

    Neo Guest

    Why the following code is compilable? The function abc() doesn't take any
    arguments, still i can call the function with arbitraty number of arguments.
    Even compiler doesn't show any warning. What the standard says?

    ----- file1.c ------
    extern unsigned abc();
    int main()
    {
    unsigned *chip_offset;
    abc(&chip_offset, 10);
    /* do something with pointer - which is errornous */
    return 0;
    }

    ----- file2.c -----
    unsigned abc()
    {
    unsigned some_address;
    some_address = 0xFFBA;
    return some_address;
    }


    -Neo
    "If you don't program yourself, life will program you!"
     
    Neo, Jan 19, 2005
    #1
    1. Advertisements

  2. But unless you're compiling this as C++, your source code doesn't say
    so. 'extern unsigned abc()' is an old-style, non-prototype
    declaration of abc(), which does *not* give the compiler any
    information about the number or types of arguments to abc(). It only
    specifies the return type (and that in an old-fashioned, deprecated
    way, lacking the 'int' after unsigned). The correct prototype
    declaration would be

    extern unsigned int abc(void);

    To avoid running into this problem in the future, you may want to
    enable whatever option your compiler has to make it insist on having
    prototype declarations in scope for all functions (in GCC it's
    -Wstrict-prototypes).

    And a nitpick: using 'extern' directly in a .c file is pretty much
    guaranteed to be a bad idea. It should only ever occur in header
    files. And the header file containing the above prototype should be
    #include'd in *both* file1.c and file2.c, to make sure it matches the
    definition and the usage of this function.
     
    Hans-Bernhard Broeker, Jan 19, 2005
    #2
    1. Advertisements

  3. Neo

    Neo Guest

    My compiler doesn't have such option. Is there any tool that i can use to
    validate my programs for ISO-C90/ANSI std. compliance.
    -Neo
     
    Neo, Jan 19, 2005
    #3
  4. Neo

    Paul Burke Guest

    What's the target, host OS, target OS (if any)?

    Paul Burke
     
    Paul Burke, Jan 19, 2005
    #4
  5. Neo

    Neo Guest

    target : TMS320C5402 DSP
    host OS : Win XP
    target OS : DSP/BIOS (by TI)

    -Neo
     
    Neo, Jan 19, 2005
    #5
  6. Such programs usually go by the family name of 'lint'. PClint appears
    to the be the generally accepted leader of the field in proprietary
    software; the FOSS world offers splint.
     
    Hans-Bernhard Broeker, Jan 19, 2005
    #6
  7. Neo

    CBFalconer Guest

    Because you specifically said you weren't defining the arguments
    here. You should have used "unsigned abc(void);" for no arguments.
     
    CBFalconer, Jan 19, 2005
    #7
  8. If you are using TI's Code Composer Studio then there definitely is control
    of the parser options. The setting is a pull-down on the Parser tab of the
    Project -> Build Options dialog.

    Scott
     
    Not Really Me, Jan 19, 2005
    #8
  9. Neo

    Neo Guest

    O'kay I turned on "Strict ANSI Mode (-ps)" Option.
    But now compiler doesn't accept non-ansi extentions provided by the Compiler
    itself. Like :
    ioport unsigned port6000;
    to declare an IO Port at 0x6000
    How it is possible to compiler the code but still in ANSI mode.

    -Neo
     
    Neo, Jan 20, 2005
    #9
  10. Neo

    Jack Klein Guest

    C allows function declarations with empty parentheses for backwards
    compatibility with code from before the ANSI standard, when the
    language did not have prototypes.

    The C standard specifically states that when you call a function
    without having a prototype in scope, if the call does not have the
    correct number and type of parameters, the behavior is undefined.
    That means it is strictly up to the programmer to make sure he gets it
    correct if he/she chooses NOT to use prototypes. A compiler is NEVER
    required to warn you about undefined behavior, and the C standard
    washes its hands of any responsibility for the result.

    There is no possible excuse at all for not using prototypes in all
    function declarations and definitions in C. Prototypes are the single
    most significant and important improvement in the 30+ year history of
    the language. Anyone who claims to be a professional C programmer and
    ever fails to use a prototype is deluding themselves.

    Empty parentheses should never appear in a function declaration or
    definition in C. NEVER.

    In a later post in the thread, you talked about using TI's Code
    Composer Studio. I use if for a different DSP family, so I don't know
    if yours is the same, but you don't want the "strict ANSI" setting on
    the Parser page. See if you have a check box for "Issue Nonserious
    Warnings" on the Diagnostics page.

    That probably won't catch this particular error, since it might equate
    the non-prototype declaration as a prototype, but I don't know for
    sure because such things never appear in my code.

    If you are going to be a professional programmer, start learning some
    basic rules now:

    1. The 'extern' keyword should NEVER appear in a source code file.

    2. There should NEVER be a function prototype in a source code file,
    unless it has the function is static and defined in the same source
    code file.

    3. All functions not static, and all external data, MUST be
    prototypes and/or declared in a header, and that header MUST be
    included by the source file that defines the function/data as well as
    every source file that calls/references the externals.

    4. There are no function declarations or definitions with (). ALL
    function declarations MUST be full prototypes. There is no "int
    main()", there is ONLY "int main(void)". There is no "extern unsigned
    abc()", there is ONLY "extern unsigned int abc(void)".

    If you do this right, the compiler will catch every single mis-matched
    function call.

    Some programmers think they are too experienced or too talented to
    have to follow what they consider "nit picky" rules like this. That
    is just a case of their egos outweighing their judgment. If you don't
    code like this, you are an accident waiting to happen, and it WILL
    happen, no matter how good or experienced you are.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c++-faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Jan 20, 2005
    #10
  11. Neo

    CBFalconer Guest

    You isolate such things into a set of non-portable routines in a
    separate file, and compile them without the ANSI setting. The bulk
    of your system is written in portable code. It can still call
    those non-portable routines. You might have, for example:

    unsigned char getport6000(void);
    void putport6000(unsigned char data);

    in a separate file, with appropriate .h header files. Your main
    program calls these.
     
    CBFalconer, Jan 20, 2005
    #11
  12. Good Rules, Jack.

    But technically, header files are source code files too. I was
    confused when I started to read your rules.

    in fact, one could be perverse and write headers
    with the .c extension, although some toolsets may
    balk (or lose functionality) with this.

    IMHO, the rules should be prefaced with:

    In the following list of rules, "source code file" is distinct
    from "header file".

    Rufus, Another Picker Of Nits

    (although I have yet to learn to use the (void) argument list)
     
    Rufus V. Smith, Jan 20, 2005
    #12
  13. Neo

    R Adsett Guest

    <snip>

    In addition to Jack's good advice (most of which I've deleted), get
    yourself a copy of lint. A good lint will catch such things as missing
    prototypes, public functions that can/should be private etc... This is
    particularly useful when you've just started to change styles and the new
    style has not become second nature yet.

    Robert
     
    R Adsett, Jan 20, 2005
    #13
  14. says...

    And that's why some folks won't use C in high reliability systems.

    Object modules _have_ to contain strong type information.
     
    Nicholas O. Lindan, Jan 20, 2005
    #14
  15. Neo

    CBFalconer Guest

    Those rules don't affect the type information in the slightest.
    They do affect the external exposure of routines and objects, and
    the linkability of systems.

    Banning C from so-called hi-reliability systems is because C
    intrinsically is unable to type things closely, and the presence of
    pointer arithmetic puts accuracy out of automatic control.
    Associated with that is the absence of range-checks, exacerbated by
    the fact that the language has no way to specify an arbitrary
    range.
     
    CBFalconer, Jan 21, 2005
    #15
  16. Neo

    Neo Guest

    Very Good Explanation of function Prototypes..... this is often overlooked
    by most C programmers or 'coz of lazziness.

    One point em nt clear about is What is the use of extern keyword in a
    function prototype. Should we use or not use extern keyword in a function
    prototype and WHY? Lets say for eg. :

    ------ main.c -----
    #include "file1.h"
    #include "abc.h"

    int main(void)
    {
    int i;
    i = sum(2,3);
    abc();
    return 0;
    }

    -------- file1.h -------
    #ifndef __FILE1_H__
    #define __FILE1_H__
    int sum(int a, int b);
    #endif

    -------- file1.c-------
    #include "file1.h"
    int sum(int a, int b)
    {
    return (a+b);
    }


    ------abc.h------
    #ifndef __ABC_H__
    #define __ABC_H__
    void abc(void);
    #endif

    -------abc.c------
    #include "abc.h"
    #include "file1.h"
    void abc(void)
    {
    int i;
    i = sum(22,33);
    }


    I compile the above Program as follows :
    gcc main.c file1.c abc.c -ansi -Wall -pedantic -Wstrict-prototypes

    Clean compilation no warnings. O'kay!
    Now, should I declare int sum(int a, int b); as
    extern int sum(int a, int b); in file1.h
    if so, why???? (I've seen some ppl. do that way).

    and there is also practice to code it something like this
    #ifdef __FILE1_C__
    #define FILE1_EXTERN
    #else
    #define FILE1_EXTERN extern
    #endif

    FILE1_EXTERN int sum(int a, int b);


    A8.1 ...."objects and functions declared outside a function are taken to be
    static, with external linkage."
    K&R II Page 211. What is the meaning of the above line???

    Thanks,
    -Neo
     
    Neo, Jan 21, 2005
    #16
  17. [... huge snip ... --- please, if you're not going to actually refer
    to any particular parts of such a long article, don't quote it in
    full...]
    It doesn't matter. Assuming you followed the rules layed out earlier
    in this thread, there's no situation left where having 'extern' would
    make a difference.

    For variables, you have to distinguish four cases of setting up a
    variable outside of any function (i.e. "at file scope").

    extern int a; /* declaration */
    int b; /* tentative definition */
    int c = 0; /* definition, external linkage */
    static int d; /* definition, internal linkage */

    The tricky one is 'b': it can be equivalent to a declaration (like
    'a'), or a definition auto-initialized to zero (like 'c'), depending
    on context. For functions, the case where it turns into a definition
    can't happen, so a and b are always equivalent, and the 'extern' is
    not necessary.

    Common practice tends to save keystrokes and file size, by omitting
    the 'extern' in prototypes.
    Please don't use this kind of names in this fashion. Names beginning
    with a double underscore aren't yours to use. They're reserved to the
    C implementation itself. If you use them yourself, you run a chance
    of conflicting with the implementation, causing all kinds of unwanted
    grief.
    This is a hack. Whether it's an evil or a clever one lies in the eye
    of the beholder.
     
    Hans-Bernhard Broeker, Jan 21, 2005
    #17
  18. Neo

    CBFalconer Guest

    .... snip Jack Kleins explanation of prototypes ...
    The answer is none. A prototype is either in a .c file, when it
    should be marked static and not be mentioned in the corresponding
    ..h file, or is in a .h file, when it should not be marked static
    and specifies an access to the .c file.

    .... snip code example ...
    For functions the static refers to their lifetime, not visibility.
    However the use of 'static' in their declaration/definition also
    removes the external linkage. The word static is used in two
    separate senses, only one of which is in the language. The actual
    qualifier 'static' in the code generally removes the default
    'external linkage' and may add the 'static lifetime' within
    functions.

    Well, at least I understand what I wrote. :)
     
    CBFalconer, Jan 21, 2005
    #18
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.