Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Trying to be generic with the linker (ld instead of g++)

36 views
Skip to first unread message

Frederick Gotham

unread,
Aug 20, 2019, 7:09:11 AM8/20/19
to

I've been doing web searches all morning to try solve this so I'm here now as last resort.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Typically if we want to combine C and C++ in one program, we can do three steps:

gcc -c *.c
g++ -c *.cpp
g++ -o prog *.o

So we use 'gcc' to compile the C code. Then we use 'g++' to compile the C++ code. Finally we use 'g++' a second time to link the object files together into one executable file.

I'm trying to be as generic as possible here in the final step (i.e. linking), and so I want to replace the second use of 'g++' with 'ld', so something like:

gcc -c *.c
g++ -c *.o
ld -o prog *.o

This works fine for the C portion of the program so long as you link with the standard C library like this:

ld -lc -o prog *.o

But if you also want to link with the C++ library (including the STL), then in theory you can try something like:

ld -lc -lc++ -o prog *.o

But this doesn't work for me on my 64-Bit x86_64 Ubuntu 18.04 personal computer. I've tried a few different switches to get the C++ standard library (e.g. lstdc++) but none of them work.

How do you link the C++ standard library in when linking with 'ld' ?

If I run "ld --version" at the command line then I get:

GNU ld (GNU Binutils for Ubuntu) 2.30
Copyright (C) 2018 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public Licence version 3 or (at your option) a later version.
This program has absolutely no warranty.

Bart

unread,
Aug 20, 2019, 7:26:06 AM8/20/19
to
On 20/08/2019 12:09, Frederick Gotham wrote:
>
> I've been doing web searches all morning to try solve this so I'm here now as last resort.
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> Typically if we want to combine C and C++ in one program, we can do three steps:
>
> gcc -c *.c
> g++ -c *.cpp
> g++ -o prog *.o
>
> So we use 'gcc' to compile the C code. Then we use 'g++' to compile the C++ code. Finally we use 'g++' a second time to link the object files together into one executable file.
>
> I'm trying to be as generic as possible here in the final step (i.e. linking), and so I want to replace the second use of 'g++' with 'ld', so something like:
>
> gcc -c *.c
> g++ -c *.o
> ld -o prog *.o
>
> This works fine for the C portion of the program so long as you link with the standard C library like this:
>
> ld -lc -o prog *.o
>
> But if you also want to link with the C++ library (including the STL), then in theory you can try something like:
>
> ld -lc -lc++ -o prog *.o
>
> But this doesn't work for me on my 64-Bit x86_64 Ubuntu 18.04 personal computer. I've tried a few different switches to get the C++ standard library (e.g. lstdc++) but none of them work.
>
> How do you link the C++ standard library in when linking with 'ld' ?
>
> If I run "ld --version" at the command line then I get:

When I wanted to find out how ld was being invoked (from gcc in my case
not gc++) I temporarily replaced ld.exe (this was on Windows) with this
program that lists the command line parameters:

#include <stdio.h>
int main (int n, char** a) {
for (int i=1; i<=n; ++i) {
printf("%d: %s\n",i,*a);
++a;
}
}

Then I ran gcc as normal. This listed some 50 different options passed
to ld even for a hello,world program. (Doubtless there will be some
existing way of doing this.)

This might help highlight what gcc/g++ is adding that is missing in your
simpler invocation.

(Don't forget to restore the original ld executable. Don't forget to
preserve the original either...)

Frederick Gotham

unread,
Aug 20, 2019, 7:34:20 AM8/20/19
to
On Tuesday, August 20, 2019 at 12:26:06 PM UTC+1, Bart wrote:

> When I wanted to find out how ld was being invoked (from gcc in my case
> not gc++) I temporarily replaced ld.exe (this was on Windows) with this
> program that lists the command line parameters:
>
> #include <stdio.h>
> int main (int n, char** a) {
> for (int i=1; i<=n; ++i) {
> printf("%d: %s\n",i,*a);
> ++a;
> }
> }
>
> Then I ran gcc as normal. This listed some 50 different options passed
> to ld even for a hello,world program. (Doubtless there will be some
> existing way of doing this.)
>
> This might help highlight what gcc/g++ is adding that is missing in your
> simpler invocation.
>
> (Don't forget to restore the original ld executable. Don't forget to
> preserve the original either...)


Very cool idea.

I was hoping to use 'ld' instead of 'g++' but if it's that complicated then I might not bother.

Ralf Fassel

unread,
Aug 20, 2019, 8:05:29 AM8/20/19
to
* Frederick Gotham <cauldwel...@gmail.com>
| But if you also want to link with the C++ library (including the STL), then in theory you can try something like:
>
| ld -lc -lc++ -o prog *.o
>
| But this doesn't work for me on my 64-Bit x86_64 Ubuntu 18.04 personal
| computer. I've tried a few different switches to get the C++ standard
| library (e.g. lstdc++) but none of them work.
>
| How do you link the C++ standard library in when linking with 'ld' ?

You could run "g++ -v" to see what g++ is doing to get the job done:

g++ --help
Usage: g++ [options] file...
Options:
--<snip-snip>--
-v Display the programs invoked by the compiler.

But the main question would be: why would you want to run ld directly?

I'd rather do

g++ -o prog prog.cxx

than some (probably version depended) magic...

R'

David Brown

unread,
Aug 20, 2019, 8:10:31 AM8/20/19
to
On 20/08/2019 13:09, Frederick Gotham wrote:
>
> I've been doing web searches all morning to try solve this so I'm here now as last resort.
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> Typically if we want to combine C and C++ in one program, we can do three steps:
>
> gcc -c *.c
> g++ -c *.cpp
> g++ -o prog *.o
>
> So we use 'gcc' to compile the C code. Then we use 'g++' to compile the C++ code. Finally we use 'g++' a second time to link the object files together into one executable file.
>
> I'm trying to be as generic as possible here in the final step (i.e. linking), and so I want to replace the second use of 'g++' with 'ld', so something like:
>
> gcc -c *.c
> g++ -c *.o
> ld -o prog *.o

Why?

What benefit do you think you'll get from using "ld" instead of "g++"
for the linking? It will just mean adding more manual flags.

>
> This works fine for the C portion of the program so long as you link with the standard C library like this:
>
> ld -lc -o prog *.o
>
> But if you also want to link with the C++ library (including the STL), then in theory you can try something like:
>
> ld -lc -lc++ -o prog *.o
>
> But this doesn't work for me on my 64-Bit x86_64 Ubuntu 18.04 personal computer. I've tried a few different switches to get the C++ standard library (e.g. lstdc++) but none of them work.
>

There are a variety of libraries that will be included automatically
when you link using "gcc" and "g++". Linking C++ code will require more
of these than simpler C code, which is why you get away with it for the
C code.

> How do you link the C++ standard library in when linking with 'ld' ?
>
> If I run "ld --version" at the command line then I get:
>

Invoke "g++ *.o" or "gcc *.o" with the "-v" flag, and it will print the
options. You may not need all of these for manual "ld" flags, but you
will no doubt need more than you have.


Keith Thompson

unread,
Aug 20, 2019, 6:51:03 PM8/20/19
to
Bart <b...@freeuk.com> writes:
[...]
> When I wanted to find out how ld was being invoked (from gcc in my case
> not gc++) I temporarily replaced ld.exe (this was on Windows) with this
> program that lists the command line parameters:
>
> #include <stdio.h>
> int main (int n, char** a) {
> for (int i=1; i<=n; ++i) {
> printf("%d: %s\n",i,*a);
> ++a;
> }
> }

"gcc -v" or "g++ -v" is easier.

[...]

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */

Keith Thompson

unread,
Aug 20, 2019, 6:59:05 PM8/20/19
to
Frederick Gotham <cauldwel...@gmail.com> writes:
> I've been doing web searches all morning to try solve this so I'm here
> now as last resort.
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> Typically if we want to combine C and C++ in one program, we can do
> three steps:
>
> gcc -c *.c
> g++ -c *.cpp
> g++ -o prog *.o
>
> So we use 'gcc' to compile the C code. Then we use 'g++' to compile
> the C++ code. Finally we use 'g++' a second time to link the object
> files together into one executable file.
>
> I'm trying to be as generic as possible here in the final step
> (i.e. linking), and so I want to replace the second use of 'g++' with
> 'ld', so something like:
>
> gcc -c *.c
> g++ -c *.o
> ld -o prog *.o
[...]

If you're doing this as a learning exercise, it's perfectly reasonable
(and others have already suggested "g++ -v"). If you're trying to do
something useful, I don't think this is a good approach.

g++ is a driver program that invokes other programs, including ld, as
needed. It knows what linker options are required to link a C++
program. That's its job. Why reinvent the wheel?

You also run the risk that the required options could change with
new releases, or with different versions of installed tools, or
with the phase of the moon. Knowing how g++ invokes ld doesn't
necessarily tell you how g++ figured out how to invoke ld, or how
that might change.

(On the other hand, if you need to link together code in different
languages, say C++ and Ada, you might need to dive a bit more deeply
into the innards.)

Bart

unread,
Aug 20, 2019, 7:28:11 PM8/20/19
to
On 20/08/2019 23:50, Keith Thompson wrote:
> Bart <b...@freeuk.com> writes:
> [...]
>> When I wanted to find out how ld was being invoked (from gcc in my case
>> not gc++) I temporarily replaced ld.exe (this was on Windows) with this
>> program that lists the command line parameters:
>>
>> #include <stdio.h>
>> int main (int n, char** a) {
>> for (int i=1; i<=n; ++i) {
>> printf("%d: %s\n",i,*a);
>> ++a;
>> }
>> }
>
> "gcc -v" or "g++ -v" is easier.

But it gives totally different output, where I have to search for the ld
options, if they are there at all (I wasn't able to find them).

For example, doing 'gcc -v hello.o' as you suggest produces:

--------------------------------------------------------
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/tdm/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-8.1.0/configure
--host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32
--target=x86_64-w64-mingw32 --prefix=/mingw64
--with-sysroot=/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64
--enable-shared --enable-static --disable-multilib
--enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes
--enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto
--enable-graphite --enable-checking=release
--enable-fully-dynamic-string --enable-version-specific-runtime-libs
--disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap
--disable-rpath --disable-win32-registry --disable-nls --disable-werror
--disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona
--with-tune=core2 --with-libiconv --with-system-zlib
--with-gmp=/c/mingw810/prerequisites/x86_64-w64-mingw32-static
--with-mpfr=/c/mingw810/prerequisites/x86_64-w64-mingw32-static
--with-mpc=/c/mingw810/prerequisites/x86_64-w64-mingw32-static
--with-isl=/c/mingw810/prerequisites/x86_64-w64-mingw32-static
--with-pkgversion='x86_64-posix-seh-rev0, Built by MinGW-W64 project'
--with-bugurl=https://sourceforge.net/projects/mingw-w64 CFLAGS='-O2
-pipe -fno-ident
-I/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include
-I/c/mingw810/prerequisites/x86_64-zlib-static/include
-I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include'
CXXFLAGS='-O2 -pipe -fno-ident
-I/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include
-I/c/mingw810/prerequisites/x86_64-zlib-static/include
-I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include'
CPPFLAGS='
-I/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include
-I/c/mingw810/prerequisites/x86_64-zlib-static/include
-I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include'
LDFLAGS='-pipe -fno-ident
-L/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/lib
-L/c/mingw810/prerequisites/x86_64-zlib-static/lib
-L/c/mingw810/prerequisites/x86_64-w64-mingw32-static/lib '
Thread model: posix
gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)
COMPILER_PATH=c:/tdm/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/;c:/tdm/bin/../libexec/gcc/;c:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/
LIBRARY_PATH=c:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/;c:/tdm/bin/../lib/gcc/;c:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib/../lib/;c:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../lib/;c:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib/;c:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../
COLLECT_GCC_OPTIONS='-v' '-mtune=core2' '-march=nocona'
c:/tdm/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/collect2.exe
-plugin
c:/tdm/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/liblto_plugin-0.dll
-plugin-opt=c:/tdm/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/lto-wrapper.exe
-plugin-opt=-fresolution=C:\Users\DESKTO~1\AppData\Local\Temp\cch8uh5p.res
-plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc
-plugin-opt=-pass-through=-lgcc_eh -plugin-opt=-pass-through=-lmoldname
-plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt
-plugin-opt=-pass-through=-lpthread -plugin-opt=-pass-through=-ladvapi32
-plugin-opt=-pass-through=-lshell32 -plugin-opt=-pass-through=-luser32
-plugin-opt=-pass-through=-lkernel32 -plugin-opt=-pass-through=-liconv
-plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc
-plugin-opt=-pass-through=-lgcc_eh -plugin-opt=-pass-through=-lmoldname
-plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt
--sysroot=C:/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64 -m i386pep
-Bdynamic
c:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib/../lib/crt2.o
c:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/crtbegin.o
-Lc:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0 -Lc:/tdm/bin/../lib/gcc
-Lc:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib/../lib
-Lc:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../lib
-Lc:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib
-Lc:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../.. hello.o
-lmingw32 -lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcrt -lpthread
-ladvapi32 -lshell32 -luser32 -lkernel32 -liconv -lmingw32 -lgcc
-lgcc_eh -lmoldname -lmingwex -lmsvcrt
c:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/crtend.o
COLLECT_GCC_OPTIONS='-v' '-mtune=core2' '-march=nocona'
--------------------------------------------------------

But using my trick, then 'gcc hello.o' generates this much clearer list
of options sent to ld.exe:

--------------------------------------------------------
1:
c:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe
2: -plugin
3: c:/tdm/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/liblto_plugin-0.dll
4:
-plugin-opt=c:/tdm/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/lto-wrapper.exe
5:
-plugin-opt=-fresolution=C:\Users\DESKTO~1\AppData\Local\Temp\ccwqayB7.res
6: -plugin-opt=-pass-through=-lmingw32
7: -plugin-opt=-pass-through=-lgcc
8: -plugin-opt=-pass-through=-lgcc_eh
9: -plugin-opt=-pass-through=-lmoldname
10: -plugin-opt=-pass-through=-lmingwex
11: -plugin-opt=-pass-through=-lmsvcrt
12: -plugin-opt=-pass-through=-lpthread
13: -plugin-opt=-pass-through=-ladvapi32
14: -plugin-opt=-pass-through=-lshell32
15: -plugin-opt=-pass-through=-luser32
16: -plugin-opt=-pass-through=-lkernel32
17: -plugin-opt=-pass-through=-liconv
18: -plugin-opt=-pass-through=-lmingw32
19: -plugin-opt=-pass-through=-lgcc
20: -plugin-opt=-pass-through=-lgcc_eh
21: -plugin-opt=-pass-through=-lmoldname
22: -plugin-opt=-pass-through=-lmingwex
23: -plugin-opt=-pass-through=-lmsvcrt
24: --sysroot=C:/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64
25: -m
26: i386pep
27: -Bdynamic
28:
c:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib/../lib/crt2.o
29: c:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/crtbegin.o
30: -Lc:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0
31: -Lc:/tdm/bin/../lib/gcc
32:
-Lc:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib/../lib
33: -Lc:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../lib
34:
-Lc:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib
35: -Lc:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../..
36: hello.o
37: -lmingw32
38: -lgcc
39: -lgcc_eh
40: -lmoldname
41: -lmingwex
42: -lmsvcrt
43: -lpthread
44: -ladvapi32
45: -lshell32
46: -luser32
47: -lkernel32
48: -liconv
49: -lmingw32
50: -lgcc
51: -lgcc_eh
52: -lmoldname
53: -lmingwex
54: -lmsvcrt
55: c:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/crtend.o
--------------------------------------------------------

Chris Vine

unread,
Aug 20, 2019, 8:08:20 PM8/20/19
to
It's not just complicated, it's non-portable, possibly even between
different versions of the same compiler, because you have to link to the
compiler's own C++ and other libraries. If you are compiling your C++
code with g++ on unix-like OSes, then including '-lstdc++ -lm
-shared-libgcc' in the link line (in addition to the C libraries) might
be enough. With clang and libc++ then '-lc++ -lm' might work. But
that is pointless: invoking g++ (or clang++) will automatically do the
job correctly for you. If you want "to be generic", then that's the
way to do it.

There are occasions when you have to call up the necessary C++
libraries directly with the linker and take your chances, accepting that
your code is brittle, usually when interfacing with some other
language's FFI where that language's linker assumes C linkage. But
your case does not fall into that category.

Tim Rentsch

unread,
Aug 22, 2019, 7:47:43 AM8/22/19
to
Frederick Gotham <cauldwel...@gmail.com> writes:

> I've been doing web searches all morning to try solve this so I'm
> here now as last resort.
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> Typically if we want to combine C and C++ in one program, we can
> do three steps:
>
> gcc -c *.c
> g++ -c *.cpp
> g++ -o prog *.o
>
> So we use 'gcc' to compile the C code. Then we use 'g++' to compile
> the C++ code. Finally we use 'g++' a second time to link the object
> files together into one executable file.
>
> I'm trying to be as generic as possible here in the final step (i.e.
> linking), and so I want to replace the second use of 'g++' with 'ld',
> so something like:
>
> gcc -c *.c
> g++ -c *.o
> ld -o prog *.o
>
> [...]

Forgive me if this is a dumb question. Is there some reason
you have to use gcc in the first step? How about doing this
instead:

g++ -x c -c *.c
g++ -x c++ -c *.cpp
g++ -o prog *.o

Substituting clang for g++ should also work here. Disclaimer: I
haven't verified anything beyond confirming that both g++ and
clang accept the -x c and -x c++ options.

Kenny McCormack

unread,
Aug 22, 2019, 8:12:09 AM8/22/19
to
In article <864l29i...@mailhub.linuxsc.com>,
Tim Rentsch <tr.1...@z991.linuxsc.com> wrote:
...
>Forgive me if this is a dumb question. Is there some reason
>you have to use gcc in the first step? How about doing this
>instead:
>
> g++ -x c -c *.c
> g++ -x c++ -c *.cpp
> g++ -o prog *.o
>
>Substituting clang for g++ should also work here. Disclaimer: I
>haven't verified anything beyond confirming that both g++ and
>clang accept the -x c and -x c++ options.

I didn't even think you needed the -x option, as long as your files have
recognized extensions. For example, when compiling normal C code, your
files have extenion ".c" and you don't need any "-x c" option. You only
need "-x" if you need to override the default *or* you're in a situation
where gcc can't figure out what type of file it is (e.g., you are reading
the program text from stdin).

There is a list somewhere of the recognized extentions and which language
they are associated with.

--
When someone tells me he/she is a Christian I check to see if I'm
still in posession of my wallet.

David Brown

unread,
Aug 22, 2019, 9:08:40 AM8/22/19
to
On 22/08/2019 14:12, Kenny McCormack wrote:
> In article <864l29i...@mailhub.linuxsc.com>,
> Tim Rentsch <tr.1...@z991.linuxsc.com> wrote:
> ...
>> Forgive me if this is a dumb question. Is there some reason
>> you have to use gcc in the first step? How about doing this
>> instead:
>>
>> g++ -x c -c *.c
>> g++ -x c++ -c *.cpp
>> g++ -o prog *.o
>>
>> Substituting clang for g++ should also work here. Disclaimer: I
>> haven't verified anything beyond confirming that both g++ and
>> clang accept the -x c and -x c++ options.
>
> I didn't even think you needed the -x option, as long as your files have
> recognized extensions. For example, when compiling normal C code, your
> files have extenion ".c" and you don't need any "-x c" option. You only
> need "-x" if you need to override the default *or* you're in a situation
> where gcc can't figure out what type of file it is (e.g., you are reading
> the program text from stdin).

"gcc file" will compile "file.c" as C, and "file.cpp" as C++. But "g++
file.c" will compile the file as C++ rather than c. (I'm not asking
anyone to like this, I just saying the way it works.) The "-x" switch
lets you override the language choices of "gcc" or "g++".

However you choose to invoke gcc, I'd also recommend you explicitly
choose the standard you want - "-std=gnu++17", "-std=c++14", or whatever
suits your needs. The default here has changed before, and will change
again in the future.

>
> There is a list somewhere of the recognized extentions and which language
> they are associated with.
>

<https://gcc.gnu.org/onlinedocs/gcc/Invoking-G_002b_002b.html>
<https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html>

Tim Rentsch

unread,
Aug 22, 2019, 3:57:57 PM8/22/19
to
gaz...@shell.xmission.com (Kenny McCormack) writes:

> In article <864l29i...@mailhub.linuxsc.com>,
> Tim Rentsch <tr.1...@z991.linuxsc.com> wrote:
> ...
>
>> Forgive me if this is a dumb question. Is there some reason
>> you have to use gcc in the first step? How about doing this
>> instead:
>>
>> g++ -x c -c *.c
>> g++ -x c++ -c *.cpp
>> g++ -o prog *.o
>>
>> Substituting clang for g++ should also work here. Disclaimer: I
>> haven't verified anything beyond confirming that both g++ and
>> clang accept the -x c and -x c++ options.
>
> I didn't even think you needed the -x option, as long as your
> files have recognized extensions. [...]

For things like C and C++, which have widely recognized ISO
standards, I don't mind taking the established rules as being
authoritative, and acting accordingly.

For tools like gcc or g++ or clang, which depend on the whims of
whichever developers happen to be contributing, and which easily
may change from one version to another, my usual practice is to
spell things out more explicitly. Here I think it helps convey
the point if the -x c and -x c++ options are made explicit rather
than being left as implied.
0 new messages