compilation error in calling a pointer to function [duplicate] - c

This question already has answers here:
How do function pointers in C work?
(12 answers)
Closed last month.
I have a C program in which this pointer to function is defined. And i am getting compilation error, what am i doing wrong?
typedef long (*myfunc)(long, long, long, long);
void mytest() {
(*myfunc)(0, 0, 0, 0);
myfunc(0, 0, 0, 0);
}
output from gcc ./test.c
$ gcc ./test.c
./test.c: In function ‘mytest’:
./test.c:106:5: error: expected expression before ‘myfunc’
106 | (*myfunc)(0, 0, 0, 0);
| ^~~~~~
./test.c:107:10: error: expected identifier or ‘(’ before numeric constant
107 | myfunc(0, 0, 0, 0);
| ^
Edit:
compiler version
$ gcc --version
gcc (GCC) 11.3.1 20220421 (Red Hat 11.3.1-3)

This is because myfunc is a type, and need to declare a variable first.
typedef long (*myfunc)(long, long, long, long);
void mytest() {
myfunc abc = 0;
abc(0, 0, 0, 0);
}

Related

C portable/cross-platform periodic timer (with millisecond resolution)?

I have been reading Signal Handler in a separate pthread using timer_create, and I decided to try implementing a C example for a periodic timer function based on the discussion there, and compiling it under MINGW64 for Windows.
It turns out, while MINGW64 can indeed emulate some aspects of POSIX under Windows, timer_create and sigevent are not part of that (/mingw64/include/signal.h does not contain declaration for sigevent - while MSYS2 /usr/include/signal.h, via /usr/include/sys/signal.h, does) - I get these errors:
test.c:153:1: error: unknown type name 'timer_t'; did you mean 'time_t'?
553 | timer_t timerId = 0;
| ^~~~~~~
| time_t
test.c: In function 'init_timer':
test.c:160:10: error: variable 'sev' has initializer but incomplete type
560 | struct sigevent sev = { 0 };
| ^~~~~~~~
test.c:160:27: warning: excess elements in struct initializer
560 | struct sigevent sev = { 0 };
| ^
test.c:160:27: note: (near initialization for 'sev')
test.c:160:19: error: storage size of 'sev' isn't known
560 | struct sigevent sev = { 0 };
| ^~~
test.c:170:22: error: 'SIGEV_THREAD' undeclared (first use in this function)
570 | sev.sigev_notify = SIGEV_THREAD;
| ^~~~~~~~~~~~
test.c:170:22: note: each undeclared identifier is reported only once for each function it appears in
test.c:174:9: warning: implicit declaration of function 'timer_create'; did you mean 'timerclear'? [-Wimplicit-function-declaration]
574 | res = timer_create(CLOCK_REALTIME, &sev, &timerId);
| ^~~~~~~~~~~~
| timerclear
test.c:180:9: warning: implicit declaration of function 'timer_settime'; did you mean 'timeGetTime'? [-Wimplicit-function-declaration]
580 | res = timer_settime(timerId, 0, &its, NULL);
| ^~~~~~~~~~~~~
| timeGetTime
test.c:160:19: warning: unused variable 'sev' [-Wunused-variable]
560 | struct sigevent sev = { 0 };
So, what I want to achieve, is a periodic timer callback of a function at a period of 10 ms (as tight as possible (*)), with C code that can compile with gcc under both MINGW64 and Linux.
Is it possible to achieve this - and if so, how? (maybe there is a library that facilitates this?)
(*) - in my experiments with MINGW64 builds on Windows 10, I've seen that nanosleep(&ts, &ts); in a while loop in main() with timestamp printouts, -- where ts = {.tv_sec = 0, .tv_nsec = 500 * 1000000} describes an interval of half a second, -- can measure anywhere between 505 and 520 ms; so I'm not sure how "tight" of a 10 ms period will be achievable - but I'd still love to know about options to implement a cross-platform periodic timer, even with a poorer timer resolution ...

I have header file in /usr/include/bpf directory called tracing.h And including it seems to causing problem. I couldn't use it in include w/w-out -I

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

SQLite extensions error, c to dll compiling

What is needed:
Compile the json1 extension for SQLite
What I did:
Reaserched the official extension page: https://sqlite.org/loadext.html
Downloaded the SQLite source code: https://www.sqlite.org/cgi/src/doc/trunk/README.md
Found 2 ways to compile a dll:
cl windows command
gcc linux command
For the cl command I installed Visual Studio and launched the vcvars32.bat file for the enviroment launch, then tried this command: cl ext/misc/json1.c sqlite3ext.h /link /dll.
Docs: https://learn.microsoft.com/en-us/cpp/build/reference/compiler-command-line-syntax?view=vs-2019
However it didnt work and I got an error: fatal error C1083: sqlite3ext.h: No such file or directory.
I have the sqlite3ext.h file and tried moving it arround but nothing worked.
Then I moved to the gcc command:
I used the Ubuntu wsl
Upadated Ubuntu
Downloaded the source code (mensioned above)
Installed the SQLite developer package (can't find it)
Used this command: gcc -g -shared sqlite/ext/misc/json1.c -o json1.dll
Found the command on the SQLite extension page mensioned above
It didn't work and I got this long error message:
sqlite/ext/misc/json1.c: In function ‘jsonEachConnect’:
sqlite/ext/misc/json1.c:2099:29: error: ‘SQLITE_VTAB_INNOCUOUS’ undeclared (first use in this function); did you mean ‘SQLITE_STATIC’?
sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
^~~~~~~~~~~~~~~~~~~~~
SQLITE_STATIC
sqlite/ext/misc/json1.c:2099:29: note: each undeclared identifier is reported only once for each function it appears in
sqlite/ext/misc/json1.c: At top level:
sqlite/ext/misc/json1.c:2501:3: warning: excess elements in struct initializer
0 /* xShadowName */
^
sqlite/ext/misc/json1.c:2501:3: note: (near initialization for ‘jsonEachModule’)
sqlite/ext/misc/json1.c:2529:3: warning: excess elements in struct initializer
0 /* xShadowName */
^
sqlite/ext/misc/json1.c:2529:3: note: (near initialization for ‘jsonTreeModule’)
sqlite/ext/misc/json1.c: In function ‘sqlite3Json1Init’:
sqlite/ext/misc/json1.c:2594:8: error: ‘SQLITE_INNOCUOUS’ undeclared (first use in this function); did you mean ‘SQLITE_IGNORE’?
SQLITE_INNOCUOUS;
^~~~~~~~~~~~~~~~
SQLITE_IGNORE
sqlite/ext/misc/json1.c:2602:10: warning: implicit declaration of function ‘sqlite3_create_window_function’; did you mean ‘sqlite3_create_function’? [-Wimplicit-function-declaration]
rc = sqlite3_create_window_function(db, aAgg[i].zName, aAgg[i].nArg,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sqlite3_create_function
sqlite/ext/misc/json1.c:2603:34: error: ‘SQLITE_SUBTYPE’ undeclared (first use in this function); did you mean ‘SQLITE_CANTOPEN’?
SQLITE_SUBTYPE | enc, 0,
^~~~~~~~~~~~~~
ANY HELP WOULD BE GREATLY APPRECIATED!
Thanks!
I had this problem with the SQLite UUID extension using "better-sqlite", but that's something else. What I did was replace everything that said SQLITE_INNOCUOUS and SQLITE_DETERMINISTIC with SQLITE_IGNORE. And it worked, at least for this extension. Something like the following:
Before:
{
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
rc = sqlite3_create_function(db, "uuid", 0, SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
sqlite3UuidFunc, 0, 0);
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "uuid_str", 1,
SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
0, sqlite3UuidStrFunc, 0, 0);
}
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "uuid_blob", 1,
SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
0, sqlite3UuidBlobFunc, 0, 0);
}
return rc;
}
After:
{
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
rc = sqlite3_create_function(db, "uuid", 0, SQLITE_UTF8 | SQLITE_IGNORE, 0,
sqlite3UuidFunc, 0, 0);
if (rc == SQLITE_OK)
{
rc = sqlite3_create_function(db, "uuid_str", 1,
SQLITE_UTF8 | SQLITE_IGNORE | SQLITE_IGNORE,
0, sqlite3UuidStrFunc, 0, 0);
}
if (rc == SQLITE_OK)
{
rc = sqlite3_create_function(db, "uuid_blob", 1,
SQLITE_UTF8 | SQLITE_IGNORE | SQLITE_IGNORE,
0, sqlite3UuidBlobFunc, 0, 0);
}
return rc;
}
Edit
I just had to declare this at the beginning of the code.
#define SQLITE_DETERMINISTIC 0x000000800
#define SQLITE_DIRECTONLY 0x000080000
#define SQLITE_SUBTYPE 0x000100000
#define SQLITE_INNOCUOUS 0x000200000

"expected ')' before numeric constant" when calling sem_init

Doing an OS programming assignment using semaphores and POSIX threads. Here's my code:
#include <pthread.h>
#include <semaphore.h>
sem_t mutex, to_b, to_a;
int main()
{
// Initialize semaphores
sem_init(&mutex, 0, 1);
sem_init(&to_b, 0, 0);
sem_init(&to_a 0, 0);
}
Compiling with gcc main.c -lpthread I get:
main.c: In function 'main':
main.c:11:24: error: expected ')' before numeric constant
main.c:11:24: error: too few arguments to function 'sem_init'
/usr/include/semaphore.h:37:12: note: declared here
Any idea what could cause this? I'm definitely calling sem_init correctly.
There is a comma missing in
sem_init(&to_a 0, 0);
It should be
sem_init(&to_a, 0, 0);
sem_init(&to_a 0, 0);
^
You're just missing a comma.
So look at the error: main.c:11:24: error: too few arguments to function 'sem_init'
Line 11 has a problem, it has "too few arguments". You're making the same call on line 10 and 9 right? but no such error, so take a careful look, character for character between line 10 and line 11.
You'll see you missed a comma:
sem_init(&to_b, 0, 0);
sem_init(&to_a 0, 0); // see it's shorter?
Should be:
sem_init(&to_a, 0, 0);

g++ compilation issue with array initialization

gcc compiles fine on the following code
enum AVMediaType {
AVMEDIA_TYPE_UNKNOWN = -1,
AVMEDIA_TYPE_VIDEO,
AVMEDIA_TYPE_AUDIO,
AVMEDIA_TYPE_DATA,
AVMEDIA_TYPE_SUBTITLE,
AVMEDIA_TYPE_ATTACHMENT,
AVMEDIA_TYPE_NB
};
static int wanted_stream[AVMEDIA_TYPE_NB]={
[AVMEDIA_TYPE_AUDIO]=-1, // Line 234
[AVMEDIA_TYPE_VIDEO]=-1,
[AVMEDIA_TYPE_SUBTITLE]=-1,
};
but g++ throws the following error
playerthread.cpp:234: error: expected primary-expression before '[' token
What's the issue here?
These kind of designated initializers aren't supported by g++, but they are by gcc. I'm not certain it's allowed in the C++ standard at all. You can see the same if you bring the code down to a very simple:
int array[10] = { [1] = 5 };
It's fine in C, not C++.

Resources