Link object files from VC++ and GCC?

Discussion in 'C++' started by Rick C. Hodgin, Jan 23, 2014.

  1. Is there a way to link object files between Visual C++ and GCC?

    I have some data that I need to encode like this:
    char* list[] = {

    Unfortunately, by default, the list[0], list[1], and list[2] pointers point
    to data that's in read-only memory. Any attempt to do something like
    memcpy(list[0], "eno", 3) fails with "Access Violation" on Windows.

    So, I discovered this syntax in GCC which creates the elements in read-write
    memory, allowing memcpy(list[0], "eno", 3) to work properly:
    char* list[] = {
    (char []) { "one" },
    (char []) { "two" },
    (char []) { "three" },

    I need the data pointed to by those list elements to be read-write in my
    application. I can use this compound literal syntax in GCC to create
    them in read-write memory, and it works in GCC. However, Visual C++
    does not support this compound literal syntax and generates about 5
    errors per line when I attempt it. :)

    I was wondering if there's a way to link in that one file, which will
    contain nothing more than a list like this sample, but with about 100
    separate elements in it representing a source code file I need to
    modify somewhat at use (replacing placeholders like "[9999]" with the
    actual runtime observed values, such as "[ 1]" and so on), to my
    Visual C++ generated code in Visual Studio 2008?

    I'm looking for something like this:
    gcc -c my_list.c
    cl /c my_prog.cpp
    link my_list.o my_prog.obj my_prog.exe

    Thank you in advance.

    Best regards,
    Rick C. Hodgin
    Rick C. Hodgin, Jan 23, 2014
    1. Advertisements

  2. In the alternative, does anyone know of a version of a Windows-based C/C++
    compiler that will honor the compound literal syntax, which will link in
    with the correct object format?

    Best regards,
    Rick C. Hodgin
    Rick C. Hodgin, Jan 23, 2014
    1. Advertisements

  3. Should work, if you get the name mangling compatible. Since both
    compilers use COFF format. But you're barking up the wrong tree: it
    doesn't make sense to do this.

    First of all you don't need the data to be read/write.

    Secondly, if you did need the data to be read/write (which you don't)
    it's trivial to specify that:

    char item_0[] = "one";

    and so on, as long item_0 is static.

    Cheers & hth.,

    - Alf
    Alf P. Steinbach, Jan 23, 2014
  4. Why not just use implementation-specific feature in VC++ to place your
    data in the read-write memory and go for const-casting it before trying
    to change? That's easier than linking GCC obj files with VC++ ones.

    You also could simply declare your 'list' as an array of arrays instead
    of the array of pointers. That would just as well allow you to edit
    those elements:

    char list[][10] = { "one", "two", "three" };

    It's been a while I used straight chars, though, take it with a grain of
    salt. Alternatively, use 'std::string':

    std::string list[] = { "one", "two", "three" };
    list[0]= "eno";

    and forget about memcpy...

    Victor Bazarov, Jan 23, 2014
  5. I have a data portion that is a source file that changes from time to time.
    It is about 100 lines long. I include that in the source file to be written
    out to the output file. It contains portions like this (greatly simplified
    for this example):

    char* sourceCode[] = {
    "if (thisThing.someOtherThing[9999].function())\r\n",
    " // Do something\r\n",
    "} else {\r\n",
    " // Do something else\r\n",

    The actual code is in another language and contains several references to
    the "[9999]" portion, which I swap out with an iterative value at runtime.
    I currently have 812 instances where this is generated and they increment
    accordingly. I have a "macro" routine that searches for [ and ] on the
    same line with 4 characters between them, and then updates the value within
    using something like sprintf(line[n] + location, "%4u", iterativeValue);.

    I have considered doing it like this:

    char sourceCode[] =
    "if (thisThing.someOtherThing[9999].function())\r\n"
    " // Do something\r\n"
    "} else {\r\n"
    " // Do something else\r\n"

    And having a read-write value that way, but there are some goals of future
    expansion where there will be more than one replacement done within. So,
    I wanted it line-by-line so I could tag on a prefix on each line indicating
    the type of value that should be there, and so on.

    The workaround I'm using right now is to add something like this at startup:

    char* sourceCode[] = {
    "if (thisThing.someOtherThing[9999].function())\r\n",
    " // Do something\r\n",
    "} else {\r\n",
    " // Do something else\r\n",

    for (int i = 0; list; i++)
    list[0] = strdup(list[0]);

    In that way, everything is read-write. But, with the compound literal
    syntax I don't need to do anything at startup, and can simply create
    read-write variables at compile-time, which are then directly usable
    at runtime. I made a macro to do this:

    #define RW(x) (char []) { x }

    char* sourceCode[] = {
    RW("if (thisThing.someOtherThing[9999].function())\r\n"),
    RW(" // Do something\r\n"),
    RW("} else {\r\n"),
    RW(" // Do something else\r\n"),

    Now the compiler does all the work for me, and I just use the read-write
    strings auto-populated for me at startup.

    No, I don't need to do it this way. There are a few design decisions
    which have factored in to me doing it this way.

    Best regards,
    Rick C. Hodgin
    Rick C. Hodgin, Jan 23, 2014
  6. Should be:

    for (int i = 0; list; i++)
    list = strdup(list);

    Best regards,
    Rick C. Hodgin
    Rick C. Hodgin, Jan 23, 2014
  7. COFF output in GCC was the key. I was able to get it working.

    Here's are the steps for a sample build:

    (1) Install MinGW on Windows with GCC and bases.
    (2) Create the two source files below.
    (3) Launch a command prompt that has the path for visual studio tools.
    (4) Execute these steps:
    (a) C:\>PATH=%PATH%;c:\mingw\bin\
    (b) C:\>g++ -c -gcoff list.cpp -o list.obj
    (c) C:\>cl /c main.cpp
    (d) C:\>link main.obj list.obj /OUT:main.exe
    (e) C:\>main
    (f) C:\>_

    #define RW(x) (char []) { x }

    extern "C"

    char* list[] =


    #include <stdlib.h>
    #include <stdio.h>

    extern "C"
    extern char* list[];

    int main(int argc, char* argv[])
    for (int i = 0; list; i++)
    list[0] = '!'; // Prove it's read-write
    puts(list); // Show it

    G++ and CL working hand-in-hand. :)

    Best regards,
    Rick C. Hodgin
    Rick C. Hodgin, Jan 23, 2014
  8. Such as?
    This option was discussed, but it is wasteful. As I say the actual
    implementation is about 100 lines of source code, some of which are 80+
    characters long, most of which are 15 characters long.
    I am currently working on developing my own C-like language that has some
    elements of C and some of C++, called RDC (Rapid Development Compiler).
    I will not support std::string in that language, along with many other C++
    features, so I am not using them for that reason. I hope someday to migrate
    all of my code to my own compiler.

    Best regards,
    Rick C. Hodgin
    Rick C. Hodgin, Jan 23, 2014
  9. Rick C. Hodgin

    David Brown Guest

    Yes, gcc runs fine on Windows. Download mingw. I believe it is even
    possible to get VS to work with such "alien" compilers, but I don't know
    how well it will handle modern C syntax highlighting.
    David Brown, Jan 23, 2014
  10. Rick C. Hodgin

    Hans-Peter Guest

    "Rick C. Hodgin" wrote in message
    You can force that the list will be in the data segment by using #pragma
    data_seg() but this will only move the pointer array in to the data segment.
    Changing the strings to fixed size will do the job:

    #pragma data_seg()
    char list[3][6] = {
    { "one" },
    { "two" },
    { "three"}

    BTW the compiler will throw an error if you set the array dimensions too

    Best regards
    Hans-Peter, Jan 24, 2014
  11. Hans-Peter, thank you for your response. I had considered using the [6]
    add-on. The actual implementation is about 100 lines, which are source
    code lines from another computer language. The lines vary in length from
    a few characters up to over 80, the average probably being 15. I had
    decided against using the [85] so as to not waste memory.

    I like this new solution, as it not only allows me to do my simple list[]
    thing, but also to use GCC and VC++ together.

    FWIW, I'm not using the GCC/VC++ solution for my project. The original
    solution I found is working just fine. :) This whole thing has been
    more of a mental exercise to try to find an alternate course.

    Best regards,
    Rick C. Hodgin
    Rick C. Hodgin, Jan 24, 2014
  12. Just curious, in what world a few hundred bytes is a waste of memory
    worthy of consideration? Are you targetting an embedded system or a
    legacy computer with 640K memory (last century technology)? Don't get
    me wrong, please, it's just that I have often enough seen real
    (significant) time wasted on finding a solution to save a few
    microseconds or a few [hundred] bytes, that usually in the end cannot be
    accounted for. I can understand when students do that in the course of
    their studies, but I don't understand the need for it when creating a
    product for others to consume.

    Victor Bazarov, Jan 24, 2014
  13. I'm getting a lot of flack over this from many people on many lists. It's
    like ... if I don't do it the way everybody else does then I'm the one who's
    wrong. And because I look toward things which are important to me, and
    because I choose to not waste memory where it doesn't need to be wasted,
    while also simplifying the source code implementation of this task, that
    it is somehow a bad choice.

    FWIW, I had a working solution after getting the first access violation error
    in the Visual Studio debugger and realizing why I got it. It took me a few
    seconds to realize what was happening, even though it was unexpected. But,
    the whole issue was one of those things I wanted to better understand. It
    seemed (and still seems) a very silly imposition, that string literals
    created in that way (as data pointed to in a read-write array) should always
    be read-only unless they are explicitly cast through such a clunky syntax as
    compound literals, a feature that not all C compilers even support.

    It was a mental exercise as much as anything else, a pursuit of a question,
    to satiate curiosity. I wound up not using the solution, but just
    discovering and testing it out. I learned many things in the process, not
    the least of which was how to integrate GCC and Visual C++ together in
    harmony. That alone was worth all the time I spent on it.
    Just curious, in what world would you deny giving help to someone in need
    simply because they top-posted? I had someone in 2011 or 2012 on the
    Trisquel mailing list tell me that I was a top poster and that he
    wasn't going to help me. I didn't even know what he was talking about
    and had to ask what that phrase "top poster" meant. When I found out
    I was floored that such a ridiculous barrier exists between the
    help-seekers, and the knowledge-holders on a forum like this.

    It really taught me something ... a concept that is so amazingly important
    to only a select few, those who desire to divide people into groups of
    "them" (top posters) and "us" (the sensible lot). Seeing your tagline here
    in this forum I was again floored. I almost wrote something to you about
    it yesterday.

    Just so you know ... there's a better way, Victor. It's called "love".
    Tear down the barriers and come out and help people in love. And if you
    want to learn the fulness of love ... He is the man, named Jesus, who is
    the Christ, the only Savior of mankind.

    Best regards,
    Rick C. Hodgin
    Rick C. Hodgin, Jan 24, 2014
  14. No, not a bad choice, by any means IMO. Just an uncommon one.
    Everybody has their priorities. Advice we *give* in part serves as
    affirmation of our being right (or at least in the right area). If
    something is recommended against our convictions, we have a choice -
    either to change our convictions or ignore the advice. And we make
    those choices constantly. Such is life.
    I hope you don't have to learn the hard way why such a silly imposition
    No argument here. Even if we don't gain anything, we always gain
    It's my help to give, I can and may deny it on any basis I choose.
    Would you help somebody who speaks rudely to you in the street or would
    you simply turn away and keep minding your own business? In such a case
    rudeness is in the eye of the beholder, of course. Similarly, I
    perceive top-posting as rudeness and choose not to involve myself in a
    message thread like that.

    Incidentally, a way to have the last word in an argument with me *here*
    is to top-post.
    Yes. So, if you care for *my* reply, now that you know that it is
    important to *me*, and you can't get it if you top-post, you *might*
    want to consider not top-post. Get it?

    Practice what you preach.

    And try not to preach.

    Victor Bazarov, Jan 24, 2014
  15. Paavo, this one of the suggestions I tried. In VS2008 it gives the
    same access violation error.

    Best regards,
    Rick C. Hodgin
    Rick C. Hodgin, Jan 24, 2014
  16. Did I top-post? I ask because I honestly don't know. I was under the
    impression that top-posting meant you posted above the quoted content.
    But maybe my understanding is still incorrect.

    Best regards,
    Rick C. Hodgin
    Rick C. Hodgin, Jan 24, 2014
  17. You did not top-post.

    Victor Bazarov, Jan 24, 2014
  18. VS2010 does the same. VS2012 differs - the resulting program runs OK.
    I don't know whether it's a good idea for you to switch to VS2012 at
    this point. This is obviously implementation-specific.

    Victor Bazarov, Jan 24, 2014
  19. Rick C. Hodgin

    Öö Tiib Guest

    So it is 8500 characters that you want to be mutable. You likely get
    better memory usage AND better performance with array (or 'std::array')
    of 'std::string's, but 8k of data are usually not worth of tinkering
    unless you have hundreds of such.
    Öö Tiib, Jan 25, 2014
  20. I have constraints on my design. I am currently writing a compiler that
    takes some aspects of C and C++, but I will not support std::array or
    std::string. As such, I am looking at some more fundamental approaches
    to processing data as I intend eventually to compile my C code in my own

    My pursuit here to have the char* list[] array point to a list of read-write
    values, instead of read-only values, also looks to that future of my compiler

    Best regards,
    Rick C. Hodgin
    Rick C. Hodgin, Jan 25, 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.