Thread: conflict in FILE and stdio

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    1,579

    conflict in FILE and stdio

    Hello everyone,


    I am porting a legacy program from other platform to Linux. I am using Red Hat Linux Enterprise 4. In the legacy program, there is a macro definition,

    Code:
    #define __FILE FILE
    in the legacy program, __FILE will be used in all the places to stands for FILE.

    Here is the program to reproduce this issue and the error message from compile, what is the most efficient way to solve this issue? Looking for your advice.

    Code:
    #define __FILE FILE
    #include <stdio.h>
    
    int main (int argc, char** argv)
    {
        return 0;
    }
    
    [root@localhost test_stdio]# gcc -g -O0 -c foo.c
    In file included from /usr/include/stdio.h:72,
                     from foo.c:2:
    /usr/include/libio.h:267: error: redefinition of `struct _IO_FILE'

    thanks in advance,
    George

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    37,605
    Well anything beginning with _ (with few exceptions) is a reserved name for the system, so you should not be using it for your own purposes.

    I'd say you've managed to find a prior use of __FILE.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Mar 2004
    Posts
    536
    Quote Originally Posted by George2 View Post
    I am porting a legacy program ...
    Been there; done that! (And the Boss told me not to change anything; just recompile.)

    What happens if you do it as follows?
    Code:
    #include <stdio.h>
    #define __FILE FILE
    More importantly: Do you have a test plan to verify the stuff after you get it to recompile? Getting it 99&#37; correct usually isn't good enough.

    D.
    Last edited by Dave Evans; 10-07-2007 at 11:28 AM.

  4. #4
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks Salem,


    Quote Originally Posted by Salem View Post
    Well anything beginning with _ (with few exceptions) is a reserved name for the system, so you should not be using it for your own purposes.

    I'd say you've managed to find a prior use of __FILE.
    I have tried to put #define after #include, and there is no compile error.

    I am very interested to learn how compiler works internally. Why put #define after #include <stdio.h> works? Why put it before will cause conflict (redefinition) -- what data types are redefined?

    In stdio.h, there is no data type called __FILE. Any ideas? :-)


    regards,
    George

  5. #5
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks Dave,


    Quote Originally Posted by Dave Evans View Post
    Been there; done that! (And the Boss told me not to change anything; just recompile.)

    What happens if you do it as follows?
    Code:
    #include <stdio.h>
    #define __FILE FILE
    More importantly: Do you have a test plan to verify the stuff after you get it to recompile? Getting it 99% correct usually isn't good enough.

    D.
    Put #define after #include works. But I do not know why put #define before #include will have compile error, since I can not find data type __FILE in stdio.h, why compiler says it is redefined?


    regards,
    George

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by George2 View Post
    Thanks Salem,




    I have tried to put #define after #include, and there is no compile error.

    I am very interested to learn how compiler works internally. Why put #define after #include <stdio.h> works? Why put it before will cause conflict (redefinition) -- what data types are redefined?

    In stdio.h, there is no data type called __FILE. Any ideas? :-)


    regards,
    George
    Are you sayingt hat stdio.h doesn't contain __FILE or that NONE of the files included by stdio.h contains __FILE? Most gcc header files I've seen will include a bunch of other header files that include further more header files, so one include may well drag in a dozen other files that in turn drag in half a dozen files each, so now you have approximately 70 files that you could have a conflict in.

    Pay particular attention to:
    /usr/include/libio.h


    It is quite clear that there is something that DOES contain __FILE inside your header-files, otherwise the alternative position wouldn't work.

    Note that __ something is defined as "implementation specific", and it's quite possiblet that there are things that

    Since a #define is only in use AFTER it is present in the file, it works to replace it later on in after the header file (because YOU are not using __FILE, but the internals of the file IO library does).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Mar 2004
    Posts
    536
    Quote Originally Posted by George2 View Post
    Put #define after #include works....
    By "works", I assume you mean that the compiler no longer chokes. In my experience, that may or may not mean that the functionality is preserved. I stand by my comment about the importance of a test plan.

    You might find that this little thing about __FILE is a problem with some versions of gcc and not with others. For the ones that give problems, there is, I believe, a very long convoluted chain of #include and #ifdef and #ifndef and #undef statements that I have never followed to the bitter end.

    From my point of view, the preferred approach would be to find all places the legacy code where __FILE is #defined and then comment out the #define statements. Find all files in the legacy code that use __FILE and replace __FILE with FILE. (Instead of a sed script or some such simple thing, you might have to look at each instance and try to figure if something "funny" is going on there that required __FILE to be something "special".)

    As matsp mentioned and salem almost mentioned, identifiers that begin with two underscores are supposed to be reserved for the implementation (the compiler writers), so the legacy code did a Bad Thing.

    To be precise, from the C standard: "All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use."

    Violations like this are not unheard of.

    The problem is when the Boss thinks that, since the legacy code works (and has been working since 1979), that porting to another operating system and/or compiler is a "slam dunk" and orders you to do the deed "without any big changes," and to have it ready by Tuesday.

    D.
    Last edited by Dave Evans; 10-08-2007 at 11:23 AM.

  8. #8
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Hi matsp,


    I can not find any __FILE in libio.h. I have attached my libio.h file from /usr/include, could you help check please? Thanks.


    regards,
    George

    Quote Originally Posted by matsp View Post
    Are you sayingt hat stdio.h doesn't contain __FILE or that NONE of the files included by stdio.h contains __FILE? Most gcc header files I've seen will include a bunch of other header files that include further more header files, so one include may well drag in a dozen other files that in turn drag in half a dozen files each, so now you have approximately 70 files that you could have a conflict in.

    Pay particular attention to:
    /usr/include/libio.h


    It is quite clear that there is something that DOES contain __FILE inside your header-files, otherwise the alternative position wouldn't work.

    Note that __ something is defined as "implementation specific", and it's quite possiblet that there are things that

    Since a #define is only in use AFTER it is present in the file, it works to replace it later on in after the header file (because YOU are not using __FILE, but the internals of the file IO library does).

    --
    Mats

  9. #9
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks Dave,


    I fully agree with you. I am just interested to learn why there is data type redefinition error, since there is no __FILE in both stdio.h and libio.h. I have attached libio.h in my previous post, could you help to have a look please?


    regards,
    George

    Quote Originally Posted by Dave Evans View Post
    By "works", I assume you mean that the compiler no longer chokes. In my experience, that may or may not mean that the functionality is preserved. I stand by my comment about the importance of a test plan.

    You might find that this little thing about __FILE is a problem with some versions of gcc and not with others. For the ones that give problems, there is, I believe, a very long convoluted chain of #include and #ifdef and #ifndef and #undef statements that I have never followed to the bitter end.

    From my point of view, the preferred approach would be to find all places the legacy code where __FILE is #defined and then comment out the #define statements. Find all files in the legacy code that use __FILE and replace __FILE with FILE. (Instead of a sed script or some such simple thing, you might have to look at each instance and try to figure if something "funny" is going on there that required __FILE to be something "special".)

    As matsp mentioned and salem almost mentioned, identifiers that begin with two underscores are supposed to be reserved for the implementation (the compiler writers), so the legacy code did a Bad Thing.

    To be precise, from the C standard: "All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use."

    Violations like this are not unheard of.

    The problem is when the Boss thinks that, since the legacy code works (and has been working since 1979), that porting to another operating system and/or compiler is a "slam dunk" and orders you to do the deed "without any big changes," and to have it ready by Tuesday.

    D.

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by George2 View Post
    Hi matsp,


    I can not find any __FILE in libio.h. I have attached my libio.h file from /usr/include, could you help check please? Thanks.


    regards,
    George
    As I stated before, the include file hierarchy in gcc is non-trivial.

    libio.h includes:
    Code:
       32:#include <_G_config.h>
       53:# include <stdarg.h>
       62:#  include <sys/cdefs.h>
      171:#  include <bits/stdio-lock.h>
      494:#   include <shlib-compat.h>
    Some of those may well include other files.

    go to /usr/include and do "grep -r __FILE ." and see what comes up - but even if you don't find something, there may be more to it than that - for example something can use macros to generate one name from another, such as
    Code:
    #define name(x) __ ## #x
     
    name(FILE) a;
    will make __FILE a;

    Just accept that __FILE is being used internally somewhere.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Why don't you do something like
    Code:
    #ifndef __FILE
    #define __FILE FILE
    #endif
    Or undefine it if it was defined... But you'd still be assuming that __FILE is the same as FILE.

  12. #12
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,398
    Quote Originally Posted by Salem View Post
    Well anything beginning with _ (with few exceptions) is a reserved name for the system, so you should not be using it for your own purposes.
    He's not "using it," he's porting code.

  13. #13
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks zacs7,


    Quote Originally Posted by zacs7 View Post
    Why don't you do something like
    Code:
    #ifndef __FILE
    #define __FILE FILE
    #endif
    Or undefine it if it was defined... But you'd still be assuming that __FILE is the same as FILE.
    I have found this line. It is my carelessness.

    I think the cause of compile error is we define something before typedef, then typedef the same thing -- __FILE. Is that correct?

    So the correct behavior is to define a datatype after typedef (typedef is real data type definition). Is that correct?

    I am interested to learn how compiler treat this internally.


    regards,
    George

  14. #14
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Yes, brewbuck. I am thinking why compiler has such error.

    Quote Originally Posted by brewbuck View Post
    He's not "using it," he's porting code.

    regards,
    George

  15. #15
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks Mats,


    Quote Originally Posted by matsp View Post

    Code:
    #define name(x) __ ## #x
     
    name(FILE) a;
    will make __FILE a;

    Mats
    What is the relationship between the above code and my question? I can not find how to use the above code to find where __FILE is defined? Any comments?


    regards,
    George

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. stdio differences windows vs linux
    By keira in forum C Programming
    Replies: 6
    Last Post: 09-14-2008, 04:42 PM
  2. Permanently deleting a file
    By civix in forum C++ Programming
    Replies: 8
    Last Post: 02-24-2008, 05:02 AM
  3. Reading integer from file.
    By esben in forum C Programming
    Replies: 4
    Last Post: 03-04-2006, 12:39 PM
  4. Binary files
    By Lionmane in forum C Programming
    Replies: 35
    Last Post: 08-25-2005, 01:56 PM
  5. Read Bytes From File Into Integer
    By ChadJohnson in forum C Programming
    Replies: 28
    Last Post: 08-16-2004, 11:57 AM