Syntax for union parameter

Discussion in 'C Programming' started by Rick C. Hodgin, Jan 29, 2014.

  1. I wrote SHA-1 to be a stand-alone program if _TEST_ME is defined, and
    an #include file if _TEST_ME is not defined. The reason you see the
    duplication is for when the program is compiled as a stand-alone. I
    did this because I offered up that code into the public domain, as I
    received it. Were it part of my library, it would use the common
    definition. The same is true for some other stand-alone utility
    programs I wrote.
    Now I've installed some cross-compilers. And rather than simply running
    xcc or ycc or zcc to get it to compile something with its built in
    features, now I'm worrying about whether or not my include paths are
    setup correctly for each, because xcc needs \xcc\include\ and ycc needs
    \ycc\include\ and zcc needs \zcc\include\, and so on. The stdint.h in
    the wrong place causes the code to fail. Wouldn't happen if the
    definition were inside of xcc, ycc, and zcc natively.
    Chomp away.
    Sorry to hear that.
    I consider C and C++ to be basically the same in this regard, so they
    are already accounted for. I've never used Fortran. I've used Pascal,
    but don't remember variable sizes (only used it in college because that's
    what they offered). Never used Ada, Haskell, or Python (apart from
    downloading programs which were already written which did something, and
    then just running those, never editing).

    Best regards,
    Rick C. Hodgin
     
    Rick C. Hodgin, Feb 9, 2014
    1. Advertisements

  2. On my system I have Microsoft's C Compiler 6.0 installed, Visual C++, and
    MinGW installed (GCC compiler toolchain on Windows). They are all installed
    properly, they all have include directories, lib directories, and so on.

    When I go to my C:\>

    Best regards,
    Rick C. Hodgin
     
    Rick C. Hodgin, Feb 9, 2014
    1. Advertisements

  3. When I go to my C:\> prompt ... where are my environment variables pointing?
    If I just type "gcc foo.c" where will it pull its include files from? Do I
    now need to setup the include file locations with every compile line?

    There are a lot of ducks to line up in a row to get C code to compile. I'm
    going to try to change that (at the sacrifice of a little bit of speed).

    Best regards,
    Rick C. Hodgin
     
    Rick C. Hodgin, Feb 9, 2014
  4. And if you leave out <stdio.h>, you can't refer to type FILE. Some
    features are defined in the core language, others in the standard
    library. The details of which goes where are not necessarily always
    entirely logical. A lot of the reasons are historical, including
    a strong desire to avoid having new standards break old code.

    I don't recall anyone claiming that C is the epitome of clean
    language and library design. It isn't.

    <stdint.h> is not optional for any implementation claiming
    to conform to C99 or later. And it's not hard to provide
    an equivalent for pre-C99 compilers; see, for example,
    (http://www.quut.com/c/q8/index.html>. (Except that you can't
    provide int64_t on pre-C99 compilers that don't have a 64-bit
    integer type.)

    As for int32_t being optional, that's just because the C standard
    doesn't require all implementations to support 32-bit 2's-complement
    integers. Systems that do support them must define int32_t --
    and systems that don't can still have conforming C implementations.
    What's odd about that? It might be defined as int one compiler, and as
    long int on another. The whole point is that you, as a programmer,
    don't have to care how it's defined.
    The essential primitive types in C are char, short, int, long,
    long long, et al. They happen to be of sizes that can vary from one
    implementation to another. This kind of flexibility was absolutely
    necessary when C was first defined; see the table of sizes near the
    beginning of K&R1. Redefining the fundamental types in a later
    standard would have broken existing code. Defining fixed-size
    types in a new standard header was the most reasonable approach.
    (It would have been nice if it had been done in C89 rather than in
    C99, but it's a bit late to complain about that now.)
    C implementations already must distribute a number of header files;
    one more isn't that big a deal. Similarly, typical programs already
    have multiple #include directives. The added cost is non-zero,
    but IMHO trivial.
    What exactly would you have wanted the C standard committee to do?

    Would you have wanted the C standard to define {s,u}{8,16,32,64}
    as keywords, while keeping the existing char, short, int, long,
    and long long as predefined types? Would u8 and unsigned char be
    different names for the same type, or distinct types? Would those
    specific types be mandatory for all implementations? Would similar
    types such as u9 be permitted?

    And since existing code, written before the introduction of
    <stdint.h>, would often define its own typedefs for fixed-size
    types, how would you deal with existing code that defined those
    names itself?

    Adding the fixed-size types in a new standard header was the best
    to avoid breaking existing code.

    If you're defining your own new language, you have the luxury
    of defining its type system as cleanly as you like. (Plenty of
    such languages have been defined over the years; few have been as
    successful as C.) If you're updating an existing language that's
    been around since the 1970s, you need to work with what you've got.
     
    Keith Thompson, Feb 9, 2014
  5. I don't know where you read that, but it's not true (as you presumably
    could have checked for yourself). I just checked with my copy of
    Microsoft Visual C++ 2010 Express (which includes a C compiler), and it
    defines uint32_t, not u_int32_t, in <stdint.h>.

    Are you unable to rely on having VS 2010 or later? If so, we can
    offer advice on how to work around the shortcomings of VS 2008 (in
    Of course someone had to check the contents of stdint.h, namely the
    authors of the implementation. Someone also had to check the rest
    of the standard library, and that the compiler works correctly.
    Implementers do this so you don't have to.

    The GNU autotools (which is where most configure scripts come
    from) are able to work with pre-C99, and probably even pre-ANSI,
    If you want to spend time checking that int32_t is really a 32-bit
    signed integer type, go ahead. Personally, I don't bother; it's such an
    unlikely problem that it's not worth my time to worry about it. If
    int32_t were built into the core language (with any non-clunky name you
    like), there would be no more or less reason to worry about it being
    defined incorrectly.
    I think Java was the *first* language I encountered (other than
    assembly) that defined fixed sizes for the fundamental types.
    And of course assembly isn't a single language; not just the operand
    sizes, but the entire language, varies drastically from one system
    to another. I've worked with plenty of languages that don't
    (Pascal and Ada, for example).

    Perhaps defining fixed-size 8, 16, 32, and 64-bit types is the wave
    of the future. C did not originally define such types, but it has,
    for all practical purposes, since 1999. (We know you don't like
    how it was done; you can stop repeating that point if you like.)
     
    Keith Thompson, Feb 9, 2014
  6. And with _TEST_ME (a reserved identifier) defined it does not compile
    because it's missing the types. Someone else will have to type them in.
    That's duplicated even if you, oddly, force others to do the
    duplication.

    I investigated a bit more and the originals from which you made your
    copy used the standard types, so you at least knew of their existence
    all along. Your contribution was to remove all reference to them and
    substitute your own typedefs -- the ones that need duplicating. If your
    compiler is too old have stdint.h you should simply have provided the
    required definitions.
    How do you know that? A compiler with built-in types might very well
    still need files in the right place to work properly -- especially a
    cross compiler. Anyway, the argument from a broken compiler install is
    a very weak one. What will RDC do to prevent mall function when it's
    not properly installed -- as a cross compiler? Straws and grasping come
    to mind.
    I take it that means you don't contest the point. Or maybe you are just
    getting bored with being right all the time?
    You are sorry that I have said something wrong or you are sorry that I
    said something right, or are you just sorry that I said anything at all?
    If you don't want to comment on something, it's simpler just to cut it
    from your reply.
    OK, take C++ out and add, I don't know..., ML, Simula, Ruby, Eiffel
    (and, for Robert, Algol). The exact number of cases is hardly the
    issue. Your experience is rather limited and that means you should be
    cautious about making claims about languages "from assembly through
    Java" as if that were some wide range.

    <snip>
     
    Ben Bacarisse, Feb 9, 2014
  7. I do not use Visual Studio 2010 or later, but only Visual Studio 2008,
    and Visual Studio 2003. I own personal copies of those applications,
    and I am using them for all development. I would switch to VS2003
    exclusively, but it is lacking the Code Preview Window that VS2008 has.

    I read it online when I tried to include stdint.h and it wasn't found.
    I searched for "Visual Studio stdint.h" and found that it was only
    included in VS2010 and later, and that there were alternatives.
    Someone on Stack Overflow (or other similar site) posted a question
    about u_int32_t being defined, but not uint32_t. I did not test it,
    and just assumed it was the case.
    I pointed out in a previous message the URL from someone who has made a
    stdint.h designed for VS2008 and earlier. I do not plan on using it
    as I already have my own typedefs in place.

    Best regards,
    Rick C. Hodgin
     
    Rick C. Hodgin, Feb 9, 2014
  8. The #ifdef block after _TEST_ME defines those types. They are the types
    for Microsoft's C/C++ compilers.
    I did not realize those types came from stdint.h, but did recognize they
    were a particular size. I assumed someone was using a particular size
    type on purpose. To keep it consistent with the rest of my code, I
    converted those references to my naming conventions, and ran the tests.
    That isn't my argument. None of the compiler installs are broken. They
    are all correct. However, because there are so many locations with the
    different include files used for their version, forgetting to point to
    the correct location could result in code that compiles correctly, yet
    is errant in operation.
    RDC uses a notably different ABI than other platforms. It is based on
    the model I designed for Exodus. It will include everything it supports
    as built-in, first-class citizens. When referenced in code there will
    not be a need to include any header files, or anything else. What you
    get with the standard libraries will be available, and upon use in source
    code those code requirements will be included and linked during launch.
    There are obvious advantages to using stdint.h, though I would still
    define my own typedefs atop those clunky names so as to make them into
    a usable form. But it's not required. I was able to accomplish the
    same thing without knowing anything about C99 or the existence of
    int32_t and so on. I came up with a natural conclusion because the
    lack of such a feature in C is so overtly obvious. Knowing about
    stdint.h would've saved me time, but not much over the years because
    the time it took me to investigate what size each was could be
    measured in minutes.
    I am sorry to hear that developers would not take the time to check
    something like that, at least the first time through, and especially
    when migrating to a new system, or a new compiler.
    It is a wide range. Assembly is the machine level. Java is a virtual
    machine, originally a fully interpreted language. The scope from the
    hardware to the entirely software has fixed components.

    My scope in computer languages is limited. I did nearly all of my
    development in assembly, xbase, and C/C++, while also writing my own
    compilers, interpreters, operating system, in assembly and C. I have
    always had a particular vision in mind for what a language should be.
    I came to that vision by examining the x86 CPU and asking myself the
    question, "Knowing what I know about its design, what would a computer
    language designed to run on that hardware need to look like?" And I
    went from there. It's the same question I asked myself about how to
    build my operating system. I didn't look at existing standards, or
    current designs. I looked at the hardware, and then went up from there.

    Over the years, and migrating into understanding Itanium later, and ARM
    more recently, I am exceedingly glad to see that the design I had for
    Exodus, and for my compiler, are exactly in line with what is required
    at the machine level. It provides high level abilities as through the
    C-like language, yet low-level abilities to not be so far away from the
    machine to prevent many features which are hidden away today from it in
    C source code, to be employed.

    Time will tell. I am one many alone working on these projects. It will
    be God Himself who allows me to complete them, as I also have a full-time
    job, a two-hour per day commute, and family time which comes before my
    work on Visual FreePro, the RDC compiler framework, the RDC programming
    language, the IDE, debugger, and virtual machine. It's a lot of work for
    one man. I keep asking people to help me, but because I am writing this
    for Jesus Christ, and not to get rich or for some other non-Jesus Christ-
    based reason, nobody is willing to help me. So, as I say, it will be God
    alone who grants me the ability to complete this project.

    It's interesting that about two hours ago I said this prayer to myself:
    Dear God, I desire to complete these projects. I desire to complete the
    work I have started. But beyond that, I desire to serve you with my life.
    I would rather forgo everything I have started with these projects and
    walk away knowing in my heart that I am serving you with my life, than
    to pursue these projects knowing that I am walking away from you with my
    life.

    My heart is focused on serving God. And I desire it more than anything
    else. Even more than completing this Village Freedom Project I began
    back in July, 2012 with the current version of Visual FreePro I am
    pursuing (virtual machine, RDC compiler framework, integrated IDE,
    debugger, and plugin framework).

    Best regards,
    Rick C. Hodgin
     
    Rick C. Hodgin, Feb 9, 2014
  9. Rick C. Hodgin

    Geoff Guest

    What? Where is your glorious IDE?

    You shouldn't be in the root to compile or develop anything. You
    should be in the document tree for the kit you are using. For Visual
    Studio 2010 that tree is C:\Users\<Username>\Documents\Visual Studio
    2010\Projects\<projectdir>.

    I have news for you: VC 6.0 and MingW are not cross compilers they are
    hosted environments.

    VC 6.0 keeps its own environment variables separate from other MS
    tools like the SDK and Visual Studio 2008 doesn't use environment
    variables for its paths, they are in the IDE settings. The only EVs VS
    20xx cares about are the ones pointing to the binaries and if you
    install each version correctly, using the defaults, they are each in a
    unique path. The only time you needed to worry about those paths was
    when mixing VS 6.0 with the Platform SDK but that is pre-200x Visual
    Studio.

    If you are using Win7/64 you can't run VS 6.0 on it except in the
    Windows XP VM and the EVs will be isolated there.
    It pulls them from its own unique path. AFAIK there is no native GCC
    for Windows, the MingW is a virtual environment with paths separate
    from Windows and the MinGW window is not the cmd prompt window.
    Yawn.
     
    Geoff, Feb 9, 2014
  10. Rick C. Hodgin

    Ian Collins Guest

    Well there you go, your design goals are pretty much orthogonal to the
    design goals of C and C++. Imagine who successful C would have been if
    it had been designed to run exclusively on a PDP7?

    The undeniable success of C comes from it not being constrained to any
    particular hardware or fixed size data types.
     
    Ian Collins, Feb 9, 2014
  11. LOL! LOL! And again I say LOL! :)
    LOL! LOL! LOL!
    That "whooshing" sound you heard when replying to my posts, Geoff, was
    my point going right past you. :) LOL! Oh my goodness. Too funny. :)
    LOL! LOL! LOL! LOL! I'm dying over here. I'm dying. LOL! LOL!

    FWIW, I run Windows 2000 Professional, or Windows Server 2003 for all of
    my personal development, using Visual Studio 2003, or Visual Studio 2008.
    I use Windows 7/64 and Visual Studio 2008 at my job.
    That's not MinGW. That's CYGWIN. MinGW is a native GCC for Windows. I
    run GCC from \mingw\bin\gcc.exe. If it loads some virtual environment
    after loading gcc.exe (using it as some kind of Windows stub) ... that is
    beyond my knowledge. However, I do invoke gcc.exe directly from the C:\>
    prompt (no matter what actual directory I might be in), and it generates
    code which runs in Windows itself (invoked from the C:\> prompt (no matter
    what actual directory I might be in)). Again, if it uses that .exe as
    some kind of stub to load a virtual environment ... that's a separate
    issue.

    I know with CYGWIN I've had issues in the past. It was the GCC tool I
    always used on Windows. It had its own linux-like environment with bash,
    and ran in its own virtual area. That is definitely not the case with
    MinGW's GCC. I was able to execute those tools alongside Microsoft's
    cl.exe compiler, and link the generated .obj files, as per the code I
    posted in the Non-constant constant thread. I had to use the COFF
    output format from GCC, which worked correctly with Microsoft's linker.
    Oh ... I thank you for this post, Geoff. I haven't laughed that much
    in a while. It is good to laugh like that. :)

    Best regards,
    Rick C. Hodgin
     
    Rick C. Hodgin, Feb 9, 2014
  12. Byte codes are interpreted. They are not native operations and exist
    inside the virtual machine program.
    No. I've tried to learn other languages at various times. It's why I
    have not moved on to use other languages. They have things which, because
    of my knowledge of assembly and how it is possible to compute data there,
    are lacking, obtuse, or backward.

    My goals have always been to bring forward a language which makes sense.
    And I pray with RDC to do exactly that. :)

    Best regards,
    Rick C. Hodgin
     
    Rick C. Hodgin, Feb 9, 2014
  13. Rick C. Hodgin

    David Brown Guest

    If you leave out the definition of "main", you will also get errors when
    compiling and linking. Does that mean "main" is not an essential part
    of the language?

    The types defined in <stdint.h> are like any other part of the
    standards-defined library - the standard says what /must/ be
    implemented, and what /may/ be implemented (with rules about how any
    particular thing must work if it /is/ implemented). But it does not
    mandate that the programmer /must/ use them! So just like in virtually
    every other programming language, you need to declare that you are using
    certain features, such as by writing #include <stdint.h>

    I could well understand if you thought that it would be nice to have
    certain common header files automatically. However, people would
    disagree about which headers to consider special in this way, and it is
    easier to be consistent if they are treated as any other header file.

    If you want a fixed bitwidth, then using int32_t is the best way to do
    it. Why do you care how it is implemented? The implementation is,
    It is in fact very common for "essential" types to be part of the
    standard library. It makes almost no difference to the language or its
    use whether it is "int" or "int32_t" that is the "primitive" type, and
    it is merely a matter of history that has determined that "int" is the
    native, "primitive" type here.
    <stdint.h> contains quite a number of different types and constants.

    (1) Distributing an extra header file is far easier for the implementer,
    and far more maintainable, than putting these types directly in the
    compiler.

    (2) A million user programs don't include <stdint.h>, because fixed size
    types are not actually needed in most code. Some kinds of code make
    heavy use of them (I use them a lot), but most *nix and Windows C code
    does not need them. So having them in the compiler would mean
    unnecessary entries in the compiler's symbol tables (native types need
    to be there too) - not that it would make a measurable difference.
    There are many ways to name your fixed size integers - a great many
    people, including me, dislike such short names as "s32". I would
    probably get used to them if they were the standard, but I don't like
    them and would never have picked them.

    I might have picked "int32", "uint32", etc., without the "_t" suffix.
    But I certainly don't mind it or find it "visual clutter". It's a
    matter of personal preference, of course.
     
    David Brown, Feb 9, 2014
  14. I cannot speak to that point since it didn't happen that way. I can speak
    to the point that the C language itself is very expressive of low-level
    abilities in a high-enough-level of understanding to make it usable by
    people. I think that feature in and of itself would've allowed it to
    cross over to other CPUs, even if the standards were indicative of some
    particular architectures which may not be like the others. I think we
    would've simply had D a lot sooner, where people modified those standards
    to meet the needs of other CPUs.

    Maybe I should call my language E.
    Perhaps. We will never know if that is true because we cannot sample
    data from the other timelines. :)

    Best regards,
    Rick C. Hodgin
     
    Rick C. Hodgin, Feb 9, 2014
  15. Rick C. Hodgin

    Ian Collins Guest

    Well how about a specific example?

    You are keen specify calling conventions, so consider what happens when
    you base that specification on your knowledge of a relatively register
    poor architecture (x86) and impose it on a register rich architecture
    (SPARC or AMD64). Neither of those push to the stack if there are
    enough registers to hold parameters (which in the case of SPARC, can be
    a large number). Even within the small x86/AMD64 family, optimal
    calling conventions are significantly different. If you want to see for
    yourself, compile

    #include <stdio.h>

    int f( int, int );

    int main(void)
    {
    printf("%d\n", f(3,4) );
    return 0;
    }

    For 32 and 64 bit and compare the assembly.
    In other words, fragmentation of the language.
     
    Ian Collins, Feb 9, 2014
  16. Rick C. Hodgin

    David Brown Guest

    You really should take some courses on basic C, or stick to using tools
    that you understand (if there are any, other than the vapourware RDC).
    Taking perfectly good code, and then mangling it because you don't know
    C, are not using a C compiler, and are incapable of even doing a simple
    google on "int32_t", is not good development work.
    /You/ don't have to do any pointing (unless you want to do something
    weird - and it is certainly possible to use different libraries with any
    given compiler. But I think such advanced usage is out of your depth).
    Based on correct installation, the /compiler/ knows where all the
    correct include files and libraries are.

    I don't know about MSVC++, but for gcc, the compiler, the libraries, the
    headers, and usually also tools such as the assembler, linker,
    librarian, etc., are all installed in a single tree. It is really easy
    to find the right include paths based on the gcc compiler binary. In
    fact, I don't believe it could possibly get any easier.

    Rick has been clutching at straws since this thread began.
    There was a time, long ago, when C lacked a convenient way to get
    implementation-independent fixed size integers. The powers that be, the
    C standards committee, realised that this was something missing and that
    people were making their own fixed size typedefs. So as this was a
    useful feature, they standardised it for C99. They did so in a way that
    was consistent with C historically, with existing C code, and with the
    way programmers expect C to work. Apart from totally subjective
    opinions about the exact choice of name, they did a perfectly good job.
    <stdint.h> is part of the implementation. When I use a new compiler
    (and I guarantee you that I have used /many/ more than you have), I rely
    on the <stdint.h> type sizes in the same way, and for the same reasons,
    as I rely on the compiler generating correct code for "x = y + z;".

    There are certainly things I /do/ check with compilers - even things
    that are clearly specified in the standards, because compiler
    implementers are mere humans and mistakes can happen. But I don't think
    any C implementer will have trouble getting the sized integers right -
    after all, even /you/ managed to do it in a few minutes.
    It is a /tiny/ range of programming languages. The fact that you even
    imagine that Assembly, C, xbase, and a smattering of Java is a "wide
    range" shows how ignorant you are.
     
    David Brown, Feb 9, 2014
  17. Rick C. Hodgin

    David Brown Guest

    Fair enough. I just know that in practice, code maintenance is often
    done badly, and documentation maintenance is done far worse. So I put
    the emphasis in having such assumptions "documented" in source code, and
    causing compile-time failures if they are broken. I agree that the
    separate documentation should include these assumptions too, but I the
    code is always the ultimate documentation.
     
    David Brown, Feb 9, 2014
  18. Sorry, I meant *not* defined. (I doesn't compiler with _TEST_ME defined
    either, but that is because of other problems no related to the types.)

    Thanks. Much clearer. Surely if your code needs a known-width type, it
    will fail its very first test. I've never found any value in testing
    the implementation -- I test my code instead.
    So, what are the languages in this wide range which do as you expect?
    None of the ones you listed as knowing fit the bill.

    <snip>
     
    Ben Bacarisse, Feb 9, 2014
  19. Rick C. Hodgin

    BartC Guest

    Why not? That range is pretty much universal now, and everyone seems to use
    their own private naming schemes anyway which can itself lead to problems.
    If it was all built-in then they wouldn't arise.

    (I've just been sorting a problem with my '#define byte unsigned char' which
    somehow clashes with a 'byte' type in windows.h. If I change my definition
    to use typedef, then it goes away, but only because C seems to allow the
    same typedef twice. The point however is if all these little types were
    built-in to the compiler, the problem wouldn't have arisen.)
    Probably not (but see below).
    I'm working on a language front-end for C, where the types have to be
    compatible. In this front-end, an exact 32-bit signed integer type can be
    represented as any of i32, int32, int:32 or int*4 (and written out in C as
    i32, which is an alias for int32_t).

    Any of these would have been fine choices to adopt in C itself (in fact
    something like int:32 is already used for bitfields, and this form can allow
    9-bit types to be defined too, although I prohibit it).

    It's not hard even for a language that has been around a long time, nor is
    it difficult to add some sort of language version control (there are already
    options for C99 and so on), and I can't believe it is out of the question
    for some refactoring program to pick out and change identifiers in source
    code which are now new keywords.

    < Would u8 and unsigned char be
    I have had u8 and c8 as distinct types, but there was very little advantage
    (and that wouldn't apply in C). I would now make them the same (if char is
    going to stay an 8-bit type).
    I don't see a problem with having the reserved words in place. Although not
    all the types need be supported.
     
    BartC, Feb 9, 2014
  20. Rick C. Hodgin

    BartC Guest

    I think these days, 'interpreted' means, at the very least, working on
    compiled byte-code, not pure source code. (I doubt Java was dynamic enough
    anyway to interpret directly from source.)
     
    BartC, Feb 9, 2014
    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.