This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/TMS320F28335: Compilation errors of redefined stido.h functions after removing extern "C" from header files

Guru 19935 points
Part Number: TMS320F28335

Tool/software: TI C/C++ Compiler

Hello,

Since I am compiling all my code as c++, I decided to remove all the extern "C" declarations from all the project header files.

After doing so, the compiler started giving me a quite a few errors about the redefined functions fgetc, fputc and sscanf.

#20 identifier "sscanf" is undefined .... C/C++ Problem
#110 expression preceding parentheses of apparent call must have (pointer-to-) function type .... C/C++ Problem
#161 declaration is incompatible with previous "std::fgetc" (declared at line 224 of "C:/ti/ccs6_2_0/ccsv6/tools/compiler/c2000_15.12.3.LTS/include/stdio.h") .... C/C++ Problem
#20 identifier "FILE" is undefined ... C/C++ Problem
#310 more than one instance of function "fputc" matches the argument list: ... C/C++ Problem
#760 "FILE" is not a type name ..... C/C++ Problem

I renamed the fgetc and fputc functions to match the prototypes in stido.h (shown below), but sscanf is still undefined.

int     fgetc(register std::FILE *_fp);

int     fputc(int _c, register std::FILE *_fp);

Is it really necessary to use the above function prototype?

It seems I am doing something wrong.  I used cstdio instead of stdio.h, but the compiler is still including stdio.h.  

Can someone point me in the right direction on how to redefine the above functions and at the same time still use C++.

Thanks,

Stephen

  • I'm confused.  Are you modifying compiler RTS header files like stdio.h?  That is not supported.  For now, I presume you only modify your own source files.

    Please pick one problem source file and make a test case out of it as described in How to Submit a Compiler Test Case.  But please submit one more file.  Also build the same file with the option --gen_preprocessor_listing.  This creates a listing file with the extension .rl.  Add the file extension .txt to it, and also attach it to your next forum post.

    Thanks and regards,

    -George

  • The C++ standard defines the C library functions as extern "C". There is no C++ linkage version of fgetc, for instance. You absolutely must have extern "C" on every declaration of the C functions inherited by C++. As George notes, typically you should not modify the TI RTS headers in any way.

    If your program works when you have functions declared extern "C", why do you need to change it?
  • I'm confused.  Are you modifying compiler RTS header files like stdio.h?  That is not supported.  For now, I presume you only modify your own source files.

    Nope, I am only changing the files in the project folder. stdio.h is contained in the compiler folder.

    Please pick one problem source file and make a test case out of it as described in How to Submit a Compiler Test Case.  But please submit one more file.  Also build the same file with the option --gen_preprocessor_listing.  This creates a listing file with the extension .rl.  Add the file extension .txt to it, and also attach it to your next forum post.

    I don't have access to the code at this time, so I created a test project that highlights the issue.  While creating the test project, I realized I needed to use  "using namespace std" to get rid of some of the compiler errors.  I am not sure why the compiler is now able to to find sscanf().

    Please see attached test project.  

    TestProject1.zip

    Stephen

  • There is an issue with Code Composer that causes the indexer not to be able to index inside #ifdef __cplusplus ... #endif.

    Please see e2e.ti.com/.../1440314
  • Is there anyway to get around this issue without having to use extern "C", i.e. maybe a C++ standard function?

    I'll try out what you mentioned when I get back to my desk.
  • Hmm.. Look for \#include directives inside extern "C" statements. For C standard header files (e.g. stdio.h), you do not need to wrap them in extern "C". If this is happening inside a header file you don't have access to, try preemptively including the header file at the top of your source file, before any extern "C" or using statements.
  • Well, you could use std::cout, but that comes with a hefty library cost. For any standard C function, you really do need the extern "C" declaration.

    Okay, you may want to remove the extern "C" from your own code, but can you just leave it there for the standard C functions? I would think you wouldn't really need to index them?
  • Looking at your test case, I now see what you are doing: you really are redefining fgetc.  You really must define this function as a C function.  You can do it with extern "C", but I would recommend moving it to another file that you would compile as a C file, so you don't need extern "C," and the indexer will still work.

    Note: the major difference between cstdio and stdio.h is that when you include stdio.h, the functions are imported to the global namespace.  If you include cstdio, you either need to refer to these functions as std::fgetc, or have a using statement, such as "using std::fgetc;" or "using namespace std;"

  • Ok, that clears up the confusion a lot. I'll try it once I get back to my desk and get back with you on what I finally decided to do.

    Thanks,
    Stephen

  • You are definitely correct about the hefty library cost. The simple program shown below took up a total of 90930 words of memory, with 79900 of it in the text section.

    Back to my issue:

    fgetc() and fputc() are calling c++ driver functions.  When I compile the file containing fgetc and fputs, the compiler complains that it can't find the c++ driver function.

    I am not putting the c++ driver header file inside the extern "C" declaration, so the fgetc and fputc functions should be calling the name mangled c++ driver functions. 

    What am I doing wrong?

    Stephen

    #include <iostream>
    
    
    int main(void) {
    	
    	return 0;
    }

  • The normal fgetc and fputc functions do not call any C++ functions. They call C functions, all the way down to the CIO interface.  Your replacement functions should not call any C++ functions, either.

    You said that "the compiler complains that it can't find the c++ driver function." What is the name of that function? What is the exact text of the error from the compiler?

    You need two files, main.cpp and myfputs.c, like so:

    /* main.cpp */
    #include <stdio.h>
    
    int main()
    {
       fputs("I am a call to fputs");
    }

    Notice that because I've included stdio.h, I can call fputs without using std::

    /* myfputs.c */
    #include <stdio.h>
    
    int fputs(const char *s, FILE *stream)
    {
         /* your implementation */
    }
    

    Notice that because this is a C file, I just include stdio.h and I get the correct prototype for fputs.

    Do not include <iostream> unless you want to use std::cout. It does not change the program in any way but to allow you to use std::cout.  If you want to use any of the C output functions (e.g. printf, puts, putchar), include either stdio.h, or cstdio