Hi i was studying C for the first time using C primer plus book then in chapter 16 about _Generic from C11 standard i wrote a program in Eclipse c/c++ and build and it produces 8 errors and warning and i don't know why here is the program and the errors
#include <stdio.h>
#include <math.h>
#define RAD_TO_DEG (180/(4 * atanl(1)))
// generic square root function
#define SQRT(X) _Generic((X),\
long double: sqrtl, \
default: sqrt, \
float: sqrtf)(X)
// generic sine function, angle in degrees
#define SIN(X) _Generic((X),\
long double: sinl((X)/RAD_TO_DEG),\
default: sin((X)/RAD_TO_DEG),\
float: sinf((X)/RAD_TO_DEG)\
)
int main(void)
{
float x = 45.0f;
double xx = 45.0;
long double xxx =45.0L;
long double y = SQRT(x);
long double yy= SQRT(xx);
long double yyy = SQRT(xxx);
printf("%.17Lf\n", y); // matches float
printf("%.17Lf\n", yy); // matches default
printf("%.17Lf\n", yyy); // matches long double
int i = 45;
yy = SQRT(i); // matches default
printf("%.17Lf\n", yy);
yyy= SIN(xxx); // matches long double
printf("%.17Lf\n", yyy);
return 0;
}
errors
make all
Building file: ../generic.c
Invoking: GCC C Compiler
gcc -std=c11 -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"generic.d" -MT"generic.d" -o "generic.o" "../generic.c"
../generic.c: In function ‘main’:
../generic.c:24:5: warning: implicit declaration of function ‘_Generic’ [-Wimplicit-function-declaration]
long double y = SQRT(x);
^
../generic.c:7:5: error: expected expression before ‘long’
long double: sqrtl, \
^
../generic.c:24:21: note: in expansion of macro ‘SQRT’
long double y = SQRT(x);
^
../generic.c:7:5: error: expected expression before ‘long’
long double: sqrtl, \
^
../generic.c:25:21: note: in expansion of macro ‘SQRT’
long double yy= SQRT(xx);
^
../generic.c:7:5: error: expected expression before ‘long’
long double: sqrtl, \
^
../generic.c:26:23: note: in expansion of macro ‘SQRT’
long double yyy = SQRT(xxx);
^
../generic.c:7:5: error: expected expression before ‘long’
long double: sqrtl, \
^
../generic.c:31:10: note: in expansion of macro ‘SQRT’
yy = SQRT(i); // matches default
^
../generic.c:13:1: error: expected expression before ‘long’
long double: sinl((X)/RAD_TO_DEG),\
^
../generic.c:33:10: note: in expansion of macro ‘SIN’
yyy= SIN(xxx); // matches long double
^
make: *** [generic.o] Error 1
14:47:53 Build Finished (took 66ms)
i have used -lm link for math.h and it produces these errors and i don't know why ?
Reason:
_Generic is not supported in gcc until version 4.9, see: https://gcc.gnu.org/wiki/C11Status
Solution:
Try a newer version of gcc.
Example:
In a.c is the code you provided:
[pengyu#GLaDOS tmp]$ gcc a.c -std=c11 -lm -Wall -pedantic
[pengyu#GLaDOS tmp]$ gcc --version | head -n 1
gcc (GCC) 4.9.1 20140903 (prerelease)
Related
Compiling and running this code:
// List the range of the long double.
#include <stdio.h>
#include <float.h>
int main() {
printf("Long double: %Lg - %Lg\n", LDBL_MIN, LDBL_MAX);
}
Gives this result:
Long double: 3.3621e-4932 - 1.18973e+4932
Yet this code:
#include <stdio.h>
#include <float.h>
int main() {
long double ld = 1.18973e+4932;
printf("Longest double: %Lg", ld);
}
Gives this warning when compiled:
gcc -std=gnu99 -o fj -Wall -Wno-format-overflow -g r2.c -lm
r2.c:4:3: warning: floating constant exceeds range of ‘double’ [-Woverflow]
4 | long double ld = 1.18973e+4932;
| ^~~~
However, if you compile:
#include <stdio.h>
#include <float.h>
int main() {
long double ld = LDBL_MAX;
printf("Longest double: %Lg\n", ld);
}
It compiles and runs:
Longest double: 1.18973e+4932
What's going on here? It should accept the numerical limit that was listed in the first program, but it does just fine with the LDBL_MAX version of it.
My compiler:
gcc --version
gcc (Debian 10.2.1-6) 10.2.1 20210110
My computer:
AMD Ryzen 5 5600G with Radeon Graphics
CPU MHz: 3057.560
BogoMIPS: 7785.19
CPU cache size: 512 KB
Debian GNU/Linux 11 (bullseye)
1.18973e+4932 is an out-of-range double constant.
LDBL_MAX is an in range long double constant.
Make the floating point constant a long double by appending an L.
Lower case l is an option too, yet harder to distinguish from 1.
// long double ld = 1.18973e+4932;
long double ld = 1.18973e+4932L; // Yet this is not quite the max
// max value better with adequate precision as
long double ld = 1.18973149535723176502e+4932L;
// Should print the same.
printf("Longest double: %.*Lg\n", LDBL_DECIMAL_DIG, ld);
printf("Longest double: %.*Lg\n", LDBL_DECIMAL_DIG, LDBL_MAX);
When coding near the limits, consider hex notation for better control in rounding issues.
long double ld = 1.1897315e+4932L; --> Infinity
long double ld = 1.18973149535723177e+4932L; --> Infinity
long double ld = 1.18973149535723176506e+4932L; --> Infinity
// 1.18973149535723176502e+4932L
long double ld = 0x1.fffffffffffffffep+16383L;
I have this header and function defined in it called long ptr = PT_REGS_PARM2(ctx); so first running command like following assuming my system config will take care of it finding this header file in /usr/include/bpf/tracing.h.
but couldn't find the header file
root#this:/home/ubuntu/Desktop/ebpf/Linux-exFilter-main/pkg/probe/bpf# clang -O2 -Wall -g -target bpf -I /usr/include/ -c kprobe_send.c -o kprobe_send.o
I also tried with - I and changing <bpf/tracing.h> to "bpf/tracing.h" not worked either.
I started this inclusion of -I after I was compiling this program and it causing error on compile, I could not understand the error but this is following
clang: error: clang frontend command failed with exit code 70 (use -v to see invocation)
#this:/home/ubuntu/Desktop/ebpf/Linux-exFilter-main/pkg/probe/bpf# clang -O2 -Wall -g-target bpf -c kprobe_send.c -o kprobe_send.o
clang: error: unknown argument: '-g-target'
clang: error: no such file or directory: 'bpf'
root#this:/home/ubuntu/Desktop/ebpf/Linux-exFilter-main/pkg/probe/bpf# clang -O2 -Wall -g -target bpf -c kprobe_send.c -o kprobe_send.o
kprobe_send.c:31:2: warning: implicit declaration of function 'srand' is invalid in C99 [-Wimplicit-function-declaration]
srand(time(NULL)); /* Seed the random number generator. */
^
kprobe_send.c:37:11: warning: implicit declaration of function 'rand' is invalid in C99 [-Wimplicit-function-declaration]
int c = randrange(MAX-i);
^
kprobe_send.c:11:22: note: expanded from macro 'randrange'
#define randrange(N) rand() / (RAND_MAX/(N) + 1)
^
kprobe_send.c:51:22: warning: implicit declaration of function 'PT_REGS_PARM2' is invalid in C99 [-Wimplicit-function-declaration]
char *ptr = PT_REGS_PARM2(ctx);
^
kprobe_send.c:51:15: warning: incompatible integer to pointer conversion initializing 'char *' with an expression of type 'int' [-Wint-conversion]
char *ptr = PT_REGS_PARM2(ctx);
^ ~~~~~~~~~~~~~~~~~~
kprobe_send.c:61:22: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'void *' [-Wint-conversion]
bpf_map_update_elem(fd,&key,&data,BPF_ANY);
^~
Error at line 37: Unsupport signed division for DAG: 0x18aff58: i64 = sdiv 0x18af668, 0x18afe20, kprobe_send.c:37:11Please convert to unsigned div/mod.
fatal error: error in backend: Cannot select: 0x18aff58: i64 = sdiv 0x18af668, 0x18afe20, kprobe_send.c:37:11
0x18af668: i64 = sra 0x189bcd8, Constant:i64<32>, kprobe_send.c:37:11
0x189bcd8: i64 = shl 0x189c4f8, Constant:i64<32>, kprobe_send.c:37:11
0x189c4f8: i64,ch,glue = CopyFromReg 0x189c018, Register:i64 $r0, 0x189c018:1, kprobe_send.c:37:11
0x189c150: i64 = Register $r0
0x189c018: ch,glue = callseq_end 0x189bc08, TargetConstant:i64<0>, TargetConstant:i64<0>, 0x189bc08:1, kprobe_send.c:37:11
0x189bfb0: i64 = TargetConstant<0>
0x189bfb0: i64 = TargetConstant<0>
What the above error even means, I thought it was complaining I did not include any headers so I started including tracing.h to cater to PT_REGS_PARM2(ctx)
How can I get rid of this error?
On this line it says unsupported sign division:
Error at line 37: Unsupport signed division for DAG: 0x18aff58: i64 = sdiv 0x18af668, 0x18afe20, kprobe_send.c:37:11Please convert to unsigned div/mod.
Is this line 37 referring to assembly or my source file? In line 37 of source file I am doing
int c = randrange(MAX-i);
Why is the above simple line is not allowed in ebpf program? This is my line 37 and rest of the bpf program
#include <linux/ptrace.h>
#include <linux/version.h>
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <string.h>
#include <sys/sendfile.h>
#include <time.h>
//#include <bpf/tracing.h>
#include <stdlib.h>
#define RAND_MAX 0x7fff
#define PERF_SAMPLE_RAW 1U << 0
#define randrange(N) rand() / (RAND_MAX/(N) + 1)
#define MAX 100000000 /* Values will be in the range (1 .. MAX) */
struct {
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
__uint(key_size, sizeof(int));
__uint(value_size, sizeof(int));
__uint(max_entries, 100);
} my_map SEC(".maps");
SEC("kprobe/__x64_sys_recvfrom")
int bpf_prog1(struct pt_regs *ctx,int fd, const char *buf, size_t count)
{
static int vektor[100000000];
int candidates[MAX];
int i;
long key;
srand(time(NULL)); /* Seed the random number generator. */
for (i=0; i<MAX; i++)
candidates[i] = i;
for (i = 0; i < MAX-1; i++) {
int c = randrange(MAX-i);
int t = candidates[i];
candidates[i] = candidates[i+c];
candidates[i+c] = t;
}
for (i=0; i<10; i++)
vektor[i] = candidates[i] + 1;
struct S {
int pid;
char cookie[90];
char *ptr;
} data={1,""};
char *ptr = PT_REGS_PARM2(ctx);
//data.pid =count;// bpf_get_current_pid_tgid();
//if(buf==NULL)
//memcpy(data.cookie,buf,20);
data.ptr=ptr;
// data.cookie[0]=buf[0];
//bpf_get_current_comm(&data.cookie, sizeof(data.cookie));
key=vektor[i];
bpf_map_update_elem(fd,&key,&data,BPF_ANY);
//bpf_perf_event_output(ctx, &my_map, 1, &data, sizeof(data));
return 0;
}
char _license[] SEC("license") = "GPL";
int _version SEC("version") = 99;
is there any info source where it says what's allowed or what's not allowed because seems to me its just picking arbitrarily what's allowed and what's not looking into ebpf
My kernel: 5.14.1
My clang: 12
libbpf installed but I'd love to find a command that tells its version and or just where it's installed.
On some link I found it says maybe/or definitely (couldn't tell the difference) be a problem of symlink on Ubuntu exact source .. what this even means does it mean I installed libbpf or something and unbuntu messed up with my symlink that help find libbpf headers? How can I understand what this link says? https://github.com/iovisor/kubectl-trace/issues/76#issuecomment-513587108
I need a complex library for some stuf in c++ or c.
So I found some useful tooltip in linux.
man complex
documentation have good example like this:
#include <math.h> /* for atan */
#include <stdio.h>
#include <complex.h>
int
main(void)
{
double pi = 4 * atan(1.0);
double complex z = cexp(I * pi);
printf("%f + %f * i\n", creal(z), cimag(z));
}
everything goes well...
But I took error every time which I tried.
> Executing task: /usr/bin/g++ -g '/home/max/Documents/c_expls/test2.cpp' -o '/home/max/Documents/c_expls/test2' <
/home/max/Documents/c_expls/test2.cpp: In function ‘int main()’:
/home/max/Documents/c_expls/test2.cpp:10:17: error: expected initializer before ‘z’
10 | double complex z = cexp(I * pi);
| ^
/home/max/Documents/c_expls/test2.cpp:11:32: error: ‘z’ was not declared in this scope
11 | printf("%f + %f * i\n", creal(z), cimag(z));
| ^
The terminal process "/bin/bash '-c', '/usr/bin/g++ -g '/home/max/Documents/c_expls/test2.cpp' -o '/home/max/Documents/c_expls/test2''" terminated with exit code: 1.
Terminal will be reused by tasks, press any key to close it.
I edited code a little bit, like adding double complex z etc.. but same machine... same error...
I think my gcc installation have lacks component. beause I tried Code::Blocks
Do you have an idea,
why my gcc doesn't know this declaration?
You need to compile with gcc and specify that you want to use the C99 standard or higher -std=c99.
For C++, use std::complex.
You need to link against the math library with the flag -lm
Using exactly your code in a file called test.c I compiled with:
gcc -o test test.c -lm
Running the binary gives the output:
./test
-1.000000 + 0.000000 * i
Consider the following snippets:
short x = 2000000000;
short x = (short)2000000000;
int x = 1000000000 * 1000000000;
Can we get an warning(/error) for these in Clang? How? Starting with what version?
Thanks,
Ciprian.
As of clang 3.3, at least, you get warnings in both cases without even trying:
/* main.c */
short x = 2000000000;
int y = 1000000000 * 1000000000;
int main()
{
return 0;
}
Compile:
$ clang -c main.c
main.c:1:11: warning: implicit conversion from 'int' to 'short' changes value
from 2000000000 to -27648 [-Wconstant-conversion]
short x = 2000000000;
~ ^~~~~~~~~~
main.c:2:20: warning: overflow in expression; result is -1486618624 with type
'int' [-Winteger-overflow]
int y = 1000000000 * 1000000000;
^
2 warnings generated.
I need to solve one problem in a virgin ANSI C (1989).
I have some pointer (void *func) to function with (int n) double parameters, and have array double values[] with n numbers. So I want to run my function with n param that are located in value.
For example, I have function:
double hypotenuse(double x, double y, double z);
so
void *func = (void *)hypotenuse; double values[3] = {5, 4, 3}; int n = 3;
and I want to do something like this:
func(n, values);
The problem is that I can't change the prototypes of the functions,
so I need to do this somehow (maybe some macros?).
The main problem is that you have to cast the pointer differently depending on the number of argument (i.e. depending on the n variable).
One way is to use a wrapper-function containing a switch statement for the argument number:
double wrapper(void *func, double args[], int n)
{
switch (n)
{
case 0:
return ((double (*)(void)) func)();
case 1:
return ((double (*)(double)) func)(args[0]);
case 2:
return ((double (*)(double, double)) func)(args[0], args[1]);
case 3:
return ((double (*)(double, double, double)) func)(args[0], args[1], args[2]);
default:
printf("Error: wrapper called with %d arguments\n", n)
break;
}
return 0.0;
}
Written late last night — but my Internet connection went down as I tried to post it. I see Joachim has written essentially the same answer.
Within limits, this will work:
#include <assert.h>
extern double function_invoker(void *func, int n, double *values);
double function_invoker(void *func, int n, double *values)
{
switch (n)
{
case 0:
return (*(double (*)(void))func)();
case 1:
return (*(double (*)(double))func)(values[0]);
case 2:
return (*(double (*)(double, double))func)(values[0], values[1]);
case 3:
return (*(double (*)(double, double, double))func)(values[0], values[1], values[2]);
default:
assert("Need more entries in the switch in function_invoker()" == 0);
return(0.0);
}
}
The obvious limits are how many entries you want to make in the switch. I've seen loosely analogous code go up to over 100 arguments; I'm not sure why that was considered necessary.
That code compiles without warnings under GCC 4.6.0 on Mac OS X 10.8.2:
$ gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition -c x.c
$
But if you go with double (*)() in place of void *, you get:
$ gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition -c x.c
x.c:3:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
x.c:5:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
$