Stripping comments from c++ code while retaining line numbering - c++

I'd like to strip the comments from a c++ file. This post provides the following solution for this:
gcc -fpreprocessed -dD -E test.c
However, this command appears to collapse long multiline comments. This causes behavior differences if the macro __LINE__ is used.
Can the gcc solution be salvaged to not change __LINE__-dependent behavior? Or, a non-gcc solution would work fine too.
Example test.c:
int main() {
/*
*
*
*
*
* comment 1
*/
// comment 2
return 0;
}
Output using gcc 4.9.2:
$ gcc -fpreprocessed -dD -E test.c
# 1 "test.c"
int main() {
# 10 "test.c"
return 0;
}
If we delete // comment 2, then we instead get the desired output without comment collapsing:
$ gcc -fpreprocessed -dD -E test.c
# 1 "test.c"
int main() {
return 0;
}

In GCC, the # directives with the numbers and file name correspond to line numbers, and thus maintain proper __LINE__ values.

Related

Optimization flag removing undefined reference to extern variable

Considering the following piece of code :
extern int var;
void foo(int & param)
{
(void) param;
}
int main(void)
{
foo(*(&var));
return 0;
}
Compiled this way :
$ g++ -Os -o test.o -c test.cpp
$ g++ test.o
But when I remove the -Os flag, there is an undefined reference to var.
What kind of optimization are enabled by -Os to skip this undefined reference ? (I tried to replace the flag by all the optimizations it enable according to the GCC documentation but I can't reproduce without -Os.
Another question, when I compile the sample in one go :
$ g++ -c test.c
There is no error even though there is no optimization flag, why ?
After performing some binary search on the flags, the relevant one appears to be -fipa-pure-const, demo here. The description is "Discover which functions are pure or constant. Enabled by default at -O1 and higher.", which presumably includes noticing that foo doesn't actually do anything with param.

Systemc Error with the library

I installed the SystemC library 2.3.1 using this tutorial.
I wrote this hello world example:
//hello.cpp
#include <systemc.h>
SC_MODULE (hello_world) {
SC_CTOR (hello_world) {
}
void say_hello() {
cout << ”Hello World systemc-2.3.0.\n”;
}
};
int sc_main(int argc, char* argv[]) {
hello_world hello(“HELLO”);
hello.say_hello();
return(0);
}
and compiled with this command:
export SYSTEMC_HOME=/usr/local/systemc230/
g++ -I. -I$SYSTEMC_HOME/include -L. -L$SYSTEMC_HOME/lib-linux -Wl,-rpath=$SYSTEMC_HOME/lib-linux -o hello hello.cpp -lsystemc -lm
When I compile the code, I got a error with the library:
In file included from hello.cpp:1:0:
/usr/local/systemc230/include/systemc.h:118:16: error: ‘std::gets’ has not been declared
using std::gets;
^~~~
How can I solve this?
std::gets has been removed in C++11 (See What is gets() equivalent in C11?)
If you're building using C++11 flag (maybe with a g++ alias), you have to disable this line in systemc.h.
Replace
using std::gets;
with
#if defined(__cplusplus) && (__cplusplus < 201103L)
using std::gets;
#endif
As guyguy333 mentioned, in new versions, g++ is an alias for C++11.
so adding -std=c++98 would solve the problem.
The compile command may like
$ g++ -std=c++98 -lsystemc -pthread main.cpp -o main
You seem to have copy pased the code from webpage as it is. Please remember “” and "" are not the same thing. On line 8
cout << ”Hello World systemc-2.3.0.\n”;
replace it with
cout << "Hello World systemc-2.3.0.\n";
and on line 13
hello_world hello(“HELLO”);
replace it with
hello_world hello("HELLO");
And then execute the code again.
GoodLuck.

Using AVX with GCC: __builtin_ia32_addpd256 not declared

If I #include <immintrin.h> I get this error:
error: '__builtin_ia32_addpd256' was not declared in this scope
I have defined __AVX__ and __FMA__ macros to make AVX avilable, but apparently this isn't enough. There is no error if I use compiler flag -mavx instead of the macros, but that solution is not acceptable. So, what else should I define to use AVX?
You shouldn't be defining __AVX__ and __FMA__ yourself - these get defined automatically when you enable the correct compiler options, e.g.
gcc -Wall -mavx ...
You can check this yourself if you're interested:
No AVX:
$ gcc -dM -E - < /dev/null | egrep "AVX|FMA"
$
AVX:
$ gcc -mavx -dM -E - < /dev/null | egrep "AVX|FMA"
#define __AVX__ 1
$
AVX + FMA:
$ gcc -mavx -mfma -dM -E - < /dev/null | egrep "AVX|FMA"
#define __AVX__ 1
#define __FMA__ 1
$
The proper solution might be to have a specific file that contains the processor specific intrinsic. And you set -mavx -mfma options only to this file. The program itself determine which version to call at runtime.
I use GCC helpers to get the best optimized version at runtime.
func_avx_fma.c
void domagic_avx_fma(...) {}
func_general.c
void domagic_general(...) {}
helper.c
void domagic_avx_fma(...);
void domagic_general(...);
typedef void (*domagic_func_t)(...);
domagic_func_t resolve_domagic()
{
__builtin_cpu_init();
if (__builtin_cpu_supports("avx") && __builtin_cpu_supports("fma")) {
return domagic_avx_fma;
}
return domagic_general;
}
void domagic(...) __attribute__ ((ifunc ("resolve_domagic")));
program.c
void domagic(...);
int main() {
domagic(...);
}
To compile
$ gcc -c func_avx_fma.c -o func_avx_fma.o -O3 -mfma -mavx
$ gcc -c func_general.c -o func_general.o -O3
$ gcc -c helper.c -o helper.o
$ ...
This approach works great on x86 (x86_64) but not all targets support these helpers

Force compile error in G++ for undeclared functions

I've installed GCC 4.8 using this method on my Mac. Everything works fine except that for certain functions like scanf and printf, the program compiles fine without any error/warning even when I did not include their respective libraries like cstdio. Is there any way that I can do to for GCC (more specifically G++, as I am dealing with C++ programs) to throw an error when such code is being fed? The following code compiles fine on my machine:
#include <iostream>
//Notice I did not include cstdio but my program uses printf later on
int main()
{
printf("Hello World!\n");
return 0;
}
I was given the suggestion to use -Werror-implicit-function-declaration -Werror or -Wall -Werror, but they don't work.
-Wimplicit-function-declaration -Werror works for me. There must be some other problems as well.
h2co3-macbook:~ h2co3$ cat baz.c
#ifndef BAILZ_OUT
#include <stdio.h>
#endif
int main()
{
printf("Hello world!\n");
return 0;
}
h2co3-macbook:~ h2co3$ gcc -o baz baz.c -Wimplicit-function-declaration -Werror
h2co3-macbook:~ h2co3$ echo $?
0
h2co3-macbook:~ h2co3$ gcc -o baz baz.c -Wimplicit-function-declaration -Werror -DBAILZ_OUT
cc1: warnings being treated as errors
baz.c: In function ‘main’:
baz.c:7: warning: implicit declaration of function ‘printf’
baz.c:7: warning: incompatible implicit declaration of built-in function ‘printf’
h2co3-macbook:~ h2co3$ echo $?
1
h2co3-macbook:~ h2co3$
The reason you get no diagnostic is that <iostream> is including the declaration of printf, which it seems to do with the c++0x or c++11 flags.
This compiles on a gcc 4.8 snapshot with the following command line:
g++ -Wall -Wextra -pedantic-errors -std=c++0x
#include <iostream>
int main()
{
printf("Hello World!\n");
return 0;
}
If you comment out the <iostream> include, or remove the C++11 compilation flags, you get an error.
impl_decl.cpp: In function 'int main()':
impl_decl.cpp:5:28: error: 'printf' was not declared in this scope
From the Annex C/Compatibility of the C++ standard from 2003:
C.1 C++ and ISO C:
C.1.3 Clause 5: expressions [diff.expr]
5.2.2
Change: Implicit declaration of functions is not allowed
Rationale: The type-safe nature of C++.
That means that implicit declarations must cause a compilation error in C++.
I'm guessing you're compiling not C++ files, but C files and you're doing that in some pre-C99 mode, which is the default in gcc. The C standard from 1999 disallows implicit declarations as well.
You may want to pass to gcc a combination of these options: -std=c99 -Werror.

Assign a value to a variable at compilation time

I'd like to assign a specific value to a variable when my code is compiling (for C and C++):
For example having :
//test.c
int main()
{
int x = MYTRICK ; (edit: changed __MYTRICK__ to MYTRICK to follow advices in comment)
printf ("%d\n", x);
return 0;
}
beeing able to do something like:
gcc -XXX MYTRICK=44 test.c -o test
and having as a result :
$./test
44
Use -D option:
gcc -DMYTRICK=44 test.c -o test
And use MYTRICK macro in your program and not __MYTRICK__. Names beginning with __ are reserved by the implementation.