liboss static declaration of ‘ioctl’ follows non-static declaration - c

I'm trying to compile a program that includes liboss's file, but when I compile I get the following error.
In file included from test.c:1:
/opt/local/include/liboss/soundcard.h:342: error: static declaration of ‘ioctl’ follows non-static declaration
/usr/include/sys/ioctl.h:97: error: previous declaration of ‘ioctl’ was here
/opt/local/include/liboss/soundcard.h:353: error: static declaration of ‘open’ follows non-static declaration
/usr/include/sys/fcntl.h:464: error: previous declaration of ‘open’ was here
/opt/local/include/liboss/soundcard.h:363: error: static declaration of ‘close’ follows non-static declaration
/usr/include/unistd.h:476: error: previous declaration of ‘close’ was here
/opt/local/include/liboss/soundcard.h:366: error: conflicting types for ‘write’
/usr/include/unistd.h:535: error: previous declaration of ‘write’ was here
The line where the first error occurs is this one.
# soundcard.h
static inline int LIBOSS_IOCTL (int x, unsigned long y,...)
{
int result;
va_list l;
va_start(l,y);
result = liboss_ioctl(x,y,l);
va_end (l);
return result;
}
# ioctl.h
__BEGIN_DECLS
int ioctl(int, unsigned long, ...);
__END_DECLS
Is there any way in which I can monkey-patch soundcard.h so that this won't be an issue?
Thnx! A.
Specs: Mac OSX 10.7.4, gcc i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1

It sounds like liboss is trying to provide an oss-compatible soundcard interface on a system where that's non-native by redefining the ioctl function to provide the OSS ioctl operations without the kernel having support for them. If this is the case, you need to make sure sys/ioctl.h (or any header that might include it) does not get included in the same source files that use soundcard.h.

Just add static to /usr/include/sys/ioctl.h:97, /usr/include/sys/fcntl.h:464, /usr/include/unistd.h:476 and /usr/include/unistd.h:535 (and undo those changes again after compilation).
In /opt/local/include/liboss/soundcard.h:366 replace int by ssize_t.
# add static
sudo nano +97 /usr/include/sys/ioctl.h
- int ioctl(int, unsigned long, ...);
+ static int ioctl(int, unsigned long, ...);
# replace int by ssize_t
sudo nano +366 /opt/local/include/liboss/soundcard.h
- static inline int LIBOSS_WRITE (int x, const void *y, size_t l)
+ static inline ssize_t LIBOSS_WRITE (int x, const void *y, size_t l)

Related

Error: definition of ‘int __atomic_compare_exchange(params1)’ ambiguates built-in declaration ‘bool __atomic_compare_exchange(params2)’

I am trying to build Berkley Db 4.8.30 on Ubuntu 20.0.4 LTS
This is what I did so far:
wget http://download.oracle.com/berkeley-db/db-4.8.30.zip
unzip db-4.8.30.zip
cd db-4.8.30
cd build_unix/
../dist/configure --prefix=/usr/local --enable-cxx
make
make install
During the compilation, I get the error messsage:
error: definition of ‘int __atomic_compare_exchange(db_atomic_t*,
atomic_value_t, atomic_value_t)’ ambiguates built-in declaration ‘bool
__atomic_compare_exchange(long unsigned int, volatile void*, void*, void*, int, int)’
The compilation flags are set correctly for my platform. Here are the relevant section of code:
atomic.h (truncated)
#if defined(DB_WIN32)
typedef DWORD atomic_value_t;
#else
typedef int32_t atomic_value_t;
#endif
/*
* Windows CE has strange issues using the Interlocked APIs with variables
* stored in shared memory. It seems like the page needs to have been written
* prior to the API working as expected. Work around this by allocating an
* additional 32-bit value that can be harmlessly written for each value
* used in Interlocked instructions.
*/
#if defined(DB_WINCE)
typedef struct {
volatile atomic_value_t value;
volatile atomic_value_t dummy;
} db_atomic_t;
#else
typedef struct {
volatile atomic_value_t value;
} db_atomic_t;
#endif
#define atomic_compare_exchange(env, p, o, n) \
__atomic_compare_exchange((p), (o), (n))
/*
* x86/gcc Compare exchange for shared latches. i486+
* Returns 1 for success, 0 for failure
*
* GCC 4.1+ has an equivalent __sync_bool_compare_and_swap() as well as
* __sync_val_compare_and_swap() which returns the value read from *dest
* http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html
* which configure could be changed to use.
*/
static inline int __atomic_compare_exchange(
db_atomic_t *p, atomic_value_t oldval, atomic_value_t newval)
{
atomic_value_t was;
if (p->value != oldval) /* check without expensive cache line locking */
return 0;
__asm__ __volatile__("lock; cmpxchgl %1, (%2);"
:"=a"(was)
:"r"(newval), "r"(p), "a"(oldval)
:"memory", "cc");
return (was == oldval);
}
I think I need to set a pragma to ignore the type safety check ... but not too sure. How do I resolve this compilation error?
The function
bool __atomic_compare_exchange(long unsigned int, volatile void*, void*, void*, int, int)
is a built-in GCC compiler function for an atomic operation. See here for details:
https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
The function
int __atomic_compare_exchange(db_atomic_t*, atomic_value_t, atomic_value_t)
seems to be a function of Berkley Db 4.8.30 and this creates a conflict. No two functions may have the same name.
The following link is a link to a patch (including patch instructions) that you can apply to solve the problem:
https://gist.github.com/danieldk/5700533

cannot compile the CUDA code when splitted into several files

I'm writing this simple cuda code and I'm unable to compile it. The code contains part of code written in C. This is the structure of the program:
read_data.c file contains a function called read_data
add.cu file contains a function called add (this is the part that should run in the GPGPU)
optimize.h file contains the necessary headers.
master.c file contains the main function.
The optimize.h file looks like follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
#include <time.h>
__global__ void add(int, float*, float*);
void read_data(char*, float**, float**, int**);
master.c file looks like follows:
#include "optimize.h"
int main(){
char* path = "./data/0";
float* base_load;
float* comfortable_temperatures;
int* comfort_index;
read_data(path, &base_load, &comfortable_temperatures, &comfort_index);
int N = 1<<20;
float *x, *y;
int i;
cudaMallocManaged(&x, N*sizeof(float));
cudaMallocManaged(&y, N*sizeof(float));
for (i = 0; i < N; i++) {
x[i] = 1.0f;
y[i] = 2.0f;
}
add<<<1, 256>>>(N, x, y);
cudaDeviceSynchronize();
// still need to read the result back.
cudaFree(x);
cudaFree(y);
}
I compiled this using the following line:
nvcc -o master master.c read_data.c add.cu
and I'm getting this error:
In file included from master.c:1:0:
optimize.h:9:12: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘void’
__global__ void add(int, float*, float*);
^
master.c: In function ‘main’:
master.c:51:26: error: ‘add’ undeclared (first use in this function)
add<<<1, 256>>>(N, x, y);
^
master.c:51:26: note: each undeclared identifier is reported only once for each function it appears in
master.c:51:31: error: expected expression before ‘<’ token
add<<<1, 256>>>(N, x, y);
I think the whatever the error is, it should be a very small one. But I cannot find it.
nvcc by default treats filenames ending in .c or .cpp as having no CUDA-specific syntax, and sends those to the host compiler. The host compiler cannot handle CUDA-specific syntax, which is why you are getting the errors.
The usual recommendations are to place your CUDA code in files ending with .cu. You can alternatively pass -x cu as a compile switch to do this.
Note that nvcc uses c++ style linkage, so you will need to arrange for correct c-style linkage if you are trying to link code in a .cu file with code in a .c file. If you have no C-specific usage, again, a simple solution may be to rename your .c file to .cpp or .cu.
There are many questions here on the cuda tag explaining how to do C++/C linkage, otherwise.

function declaration problem in multi file c project

I have a project that includes three files in codeblocks:
main.c :
#include <stdio.h>
#include <conio.h>
int global = 10;
void f1(int);
void f1_1(int);
void f2(void);
int main()
{
int x = 5;
printf("inside main file");
getch();
f1(x);
f2();
getch();
return 0;
}
file1.c :
#include <stdio.h>
#include <conio.h>
void f1(int x)
{
printf("\ninside file1 >> f1 and x = %i", x);
getch();
f1_1(x);
}
void f1_1(int x)
{
printf("\ninside file1 >> f1 >> f1_1 and x = %i", x);
getch();
}
file2.c :
#include <stdio.h>
#include <conio.h>
extern int global;
void f2()
{
printf("\ninside file2 >> f2 function , global var = %i", global);
getch();
}
When I compiled it, I got these warnings:
c|8|warning: implicit declaration of function 'f1_1'; did you mean 'f1'? [-Wimplicit-function-declaration]
c|11|warning: conflicting types for 'f1_1'
What should I do for this?
void f1(int);
void f1_1(int);
void f2(void);
Should be:
extern void f1(int);
extern void f1_1(int);
extern void f2(void);
Or, as #kiranBiradar points out, you can declare them in header files
file1.h
#pragma once
extern void f1(int);
extern void f1_1(int);
file2.h
#pragma once
extern void f2(void);
Note the use of the extern keyword. When you forward declare a function in a file as void f(void), the symbol 'f' is public, meaning other compilation units can reference it. When you declare it as extern void f(void), then the compiler doesn't expect the function to be defined in that compilation unit and leaves it up to the linker to find that symbol.
This is the perfect time to learn about the important concept of translation units.
Each single source file, with all included header file, forms a single translation unit. Each translation unit is separate and distinct and compiled stand-alone without any knowledge of other translation units.
That means symbols declared in e.g. the main.c source file will not be known in the file1.c source file.
When you compile file1.c the compiler simply doesn't know about the f1_1 function declaration you have in the main.c source file, so you get a warning about that fact.
To solve your problem, you need to declare the f1_1 function in the file1.c file. Either by adding a forward declaration (like the one you have in main.c), or moving the whole function definition (implementation) of f1_1 above the f1 function.
Or you could create a single header file which contains all the declarations needed (for the f1, f1_1, f2 function, plus the global external variable declaration), and include this single header file in all your source files. This solution works best if you have multiple symbols (functions, variables, etc.) that are used in multiple translation units.
My personal recommendation is this: Since the f1_1 function is only used internally inside the file1.c source file, move its definition above f1, and make it static. Then remove its declaration from the main.c source file.
Regarding the "implicit declaration" and "conflicting types" warnings, it's because in older standards of C it was allowed to not declare functions and the compiler would create an implicit declaration by guessing the declaration based on the first call of the function.
The important part about the guessing is that only the arguments were guessed, the return type would always be int.
I don't know the exact wording in the specifications about this since it was removed in the C99 specification, but most compilers still allow this with only emitting a warning instead of an error. This is where the first warning comes from.
However, the return type of int is still being used. And since your f1_1 function is declared to return void later in the file1.c source file, there's a mismatch between the guessed declaration (int f1_1(int)) and the actual declaration (void f1_1(int)) which leads to the second warning.

GCC typeof extension

I don't understand why this works:
/* gcc range extension */
__extension__ static int fn(int n)
{
switch (n) {
case 0: return 0;
case 1 ... 1000: return 1;
default: return -1;
}
}
But this does not:
/* gcc typeof extension */
__extension__ static void fn(int n)
{
typeof(n) a = n;
printf("%d\n", a);
}
gcc returns:
demo.c:14: warning: implicit declaration of function ‘typeof’
demo.c:14: warning: nested extern declaration of ‘typeof’
demo.c:14: error: expected ‘;’ before ‘a’
demo.c:16: error: ‘a’ undeclared (first use in this function)
demo.c:16: error: (Each undeclared identifier is reported only once
demo.c:16: error: for each function it appears in.)
I know I can compile with -std=gnu99 to avoid the error but the first one works with -std=c99 and uses also an extension
Non-ANSI compatible keywords are not ever reenabled by __extension__ (the only effect of __extension__ is warning suppression for -pedantic). Use __typeof__ if you want to compile in ANSI mode.
If you are writing a header file that must work when included in ISO C programs, write __typeof__ instead of typeof.
Refer to this link for a more elaborate description and the possible fixes.
Note: __extension__ has no effect aside from suppressing the warnings when using ANSI C -pedantic mode.
So something like this:
/* gcc typeof extension */
__extension__ static void fn(int n)
{
__typeof__(n) a = n;
printf("%d\n", a);
}

No warning or error indication when variable defined as static but declared as extern

I came across some code today that surprised me. A variable was defined (outside of a function) in the .c file as being static. However, in the .h file it was declared as being extern. Here is a similar example of the code:
Structure definitions and declaration in .h:
typedef struct
{
unsigned char counter;
unsigned char some_num;
} One_Struct;
typedef struct
{
unsigned char counter;
unsigned char some_num;
const unsigned char * p_something;
} Another_Struct;
typedef struct
{
One_Struct * const p_one_struct;
Another_Struct * const p_another_struct;
} One_Useful_Struct;
extern One_Useful_Struct * const p_my_useful_struct[];
Definition and initialization in .c:
static One_Useful_Struct * const p_my_useful_struct[MAX_USEFUL_STRUCTS] =
{
&p_my_useful_struct_regarding_x,
&p_my_useful_struct_regarding_y,
};
Question:
So my question is, why didn't I receive a compiler error or warning?
The code has been successfully running in other projects for some time now. I did note that the pointer is never used outside of the .c file in which it is defined and was properly defined as static (I removed the external declaration). The only reason that I found it was because I ran Lint on the project and Lint picked it up.
It's certianly not standard C. GCC and clang both detect and give an error on this case:
$ gcc example.c
example.c:4: error: static declaration of ‘x’ follows non-static declaration
example.c:3: error: previous declaration of ‘x’ was here
$ clang example.c
example.c:4:12: error: static declaration of 'x' follows non-static declaration
static int x;
^
example.c:3:12: note: previous definition is here
extern int x;
^
1 error generated.
You must be using a pretty permissive compiler - maybe Visual Studio? I just checked on my Windows machine and VS2003 accepts my example program silently. Adding /Wall does give a warning:
> cl /nologo /Wall example.c
example.c
example.c(4) : warning C4211: nonstandard extension used : redefined extern to static
Looks to me like you're using an extension of whatever compiler it is that you're using.

Resources