I am trying to build in MinGW (this builds fine in VS2005) but facing this error at:
#ifndef int64
#define int64 __int64 /**< Win32 version of 64-bit integers */
#endif
// also in class.h
#ifndef FADDR
#define FADDR
typedef int64 (*FUNCTIONADDR)(void*,...); /** the entry point of a module function */
#endif
and the error I get is:
error: expected declaration specifiers or '...' before '*' token
typedef int64 (*FUNCTIONADDR)(void*,...); /** the entry point of a module function */
^
Any suggestions about how to handle this?
Thank you.
__int64 is part from MSVC and doesn't exist in GCC. You can use int64_t from stdint.h instead. Simple check:
#ifdef _MSC_VER
typedef __int64 int64;
#else
#include <stdint.h>
typedef int64_t int64;
#endif
Related
I'm trying to write a C++ library, which is going to target an ARM Linux system, but leaving C-compatible "bindings" and structs for using with CFFI on other languages.
The library deals with a serial stream that I don't control, and that I want to de-serialize.
I have the following (simplified) struct on stream.h:
#pragma once
#include "cpp_compat.h"
#include <stdbool.h>
#include <stdint.h>
#define BB_FRAME_IQ_SAMPLES_COUNT 512
#define BB_FRAME_MAGIC 0xAA5555AA
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct __attribute__((__packed__))
{
/** Every frame starts with BB_FRAME_MAGIC. */
uint32_t magic;
/** Baseband IQ samples. */
fcomplex_t bb_iq_samples[BB_FRAME_IQ_SAMPLES_COUNT];
uint8_t someparams[9]; // simplification
uint32_t reserved_n[6];
uint32_t crc;
} bb_frame_t;
#ifdef __cplusplus
}
#endif
fcomplex_t is where the C/C++ compatibility happens, thanks to cpp_compat.h:
#pragma once
#ifdef __cplusplus
#include <complex>
using fcomplex_t = std::complex<float>;
#else
#include <complex.h>
typedef _Complex float fcomplex_t;
#endif
However, I'm having this warning when building the code in C++:
[build] stream.h:41:37: warning: ignoring packed attribute because of unpacked non-POD field ‘fcomplex_t <unnamed struct>::bb_iq_samples [512]’
[build] 41 | fcomplex_t bb_iq_samples[BB_FRAME_IQ_SAMPLES_COUNT];
[build] | ^~~~~~~~~~~~~
And this scares me because I really need the packed attribute to work to correctly de-serialize the frames from the serial stream.
The compiler is arm-linux-gnueabihf-g++ (GCC) 12.2.1 20221203 [releases/gcc-12 revision c03cb4b762aceeba95da918b042583af0d9f6030]. I got it from a buildroot using the Linaro toolchain.
So the question is, how can I make this work without errors?
P.S.: It's worth noting that the C++ standard guarantees that std::complex<float> and _Complex float are memory-compatible.
EDIT 1: In the meanwhile, I found out that x86's GCC also complains about the issue but Clang (tested with version 16) does not. Seems to be something GCC-specific.
Raised the problem on GCC.
It's apparently an intended behaviour of the compiler.
More details in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108342
I saw some code in glog like below:
#if #ac_cv_have_libgflags#
#include <gflags/gflags.h>
#endif
#ac_google_start_namespace#
#if #ac_cv_have_uint16_t# // the C99 format
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
#elif #ac_cv_have_u_int16_t# // the BSD format
What is the role of the # symbol in c++, how to use it?
Those "#ac...#" tokens are for autoconf aka ./configure. They are replaced before the file is compiled, by the preprocessor called m4.
After the m4 preprocessing is done on your example, but before the C preprocessing is done, it might look like this:
#if 1
#include <gflags/gflags.h>
#endif
namespace google {
#if 1 // the C99 format
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
#elif 0 // the BSD format
Some of the tokens in your example are populated by a file like this: https://android.googlesource.com/platform/external/open-vcdiff/+/0a58c5c2f73e5047b36f12b5f12b12d6f2a9f69d/gflags/m4/google_namespace.m4
For more on autoconf, see: http://www.cs.columbia.edu/~sedwards/presentations/autoconf1996.pdf
I have this code:
#include <stdint.h>
#define internal static
#define local_persist static
#define global_variable static
#define Pi32 3.14159265359f
typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;
typedef int32 bool32;
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;
typedef float real32;
typedef double real64;
#include "someheader.h"
// etc
And in the someheader.h file I have:
struct game_sound_output_buffer
{
int16* Samples;
int SampleCount;
int SamplesPerSecond;
};
I am using Visual Studio and I get these errors on the line with the int16* variable:
error C2143: syntax error : missing ';' before '*'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
Why does this happen? I typedefed before including the header file.
And the weirder thing, it works fine if I compile from the command line
cl -FC -Zi file.cpp user32.lib Gdi32.lib
declaring the typedefs in one file and then including another file after them does not add those typedefs into that other file. All including a file does is it copy and paste the code from the file into the file doing the including. The original file still does not know about those types so when the compiler gets to it there will be an error.
What you need to do is include the file that has the typedefs in it in the file that is using them
mytypes.h
#include <stdint.h>
#define internal static
#define local_persist static
#define global_variable static
#define Pi32 3.14159265359f
typedef int8_t int8;
typedef int16_t int16;
//...
header file that uses the types
#include "mytypes.h" // oh now I see all of those types and I can use them
struct game_sound_output_buffer
{
int16* Samples;
int SampleCount;
int SamplesPerSecond;
};
Put your typedefs in their own header, something like someotherheader.h, and then include that at the top of someheader.h.
In your example you used the type int16 but you did only define int16_t!
Anyway, It is good practive to include the header file that supplies the types in the file that uses the types, so you should put the definitions in their own file and include that in someheader.h.
I am using -D_FILE_OFFSET_BITS=64 flag while compiling my application on Unix. It gets built properly on RHEL, SuSE, HP-uX and AIX.
On Solaris, I am getting an error for following:
long lPos = 0L;
long UTMPSIZE = sizeof(struct utmp);
int fd = 0;
fd = open("/etc/utmp", O_RDONLY);
UTMPSIZE = sizeof(struct utmpx);
lPos = lseek(fd, -UTMPSIZE, SEEK_END); // error: conversion from `long int' to non-scalar type `off_t' requested
I read somewhere that using -D_FILE_OFFSET_BITS=64, the long gets #defined to off_t.
If that is so, why this error happens?
I wrote the same steps in a cpp program, compiled and executed on a soalris system, and it works. However only while compiling the application, the error is seen.
This is what i have in types.h:
#if __STDC__ - 0 == 0 && !defined(_NO_LONGLONG)
typedef long long longlong_t;
typedef unsigned long long u_longlong_t;
#else
/* used to reserve space and generate alignment */
typedef union {
double _d;
int32_t _l[2];
} longlong_t;
typedef union {
double _d;
uint32_t _l[2];
} u_longlong_t;
#endif /* __STDC__ - 0 == 0 && !defined(_NO_LONGLONG) */
#ifndef _OFF_T
#define _OFF_T
#if defined(_LP64) || _FILE_OFFSET_BITS == 32
typedef long off_t; /* offsets within files */
#elif _FILE_OFFSET_BITS == 64
typedef longlong_t off_t; /* offsets within files */
#endif
#if defined(_LARGEFILE64_SOURCE)
#ifdef _LP64
typedef off_t off64_t; /* offsets within files */
#else
typedef longlong_t off64_t; /* offsets within files */
#endif
#endif /* _LARGEFILE64_SOURCE */
#endif /* _OFF_T */
If I use long long in code, the error is now changed to "long long int".
To solve above problem, I have added #define _FILE_OFFSET_BITS 64. It was found that in one of the header same flag value was set to 32. I don't know what happened but, using compile time flag did not override that #define. I then added following after the #include:
#ifdef <SunOS>
#undef _FILE_OFFSET_BITS
#define _FILE_OFFSET_BITS 64
#endif
This rectifies the compile time error. But now there is another problem, the stat structure members after stat() call are not getting populated properly. I have no clue why is it happening so.
Any help here is much appreciated..
The "non-scalar type" part of the error message is suspicious, as it implies that off_t is being implemented as some kind of struct instead of a 64-bit integer.
Is gcc up-to-date on the Solaris machine? Specifically, if you are using gcc 4.3.0 on Solaris, you may be experiencing GCC bug 30513 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=30513). If you look at comment 9 in the bug report, you can see they get a very similar error: "conversion from 'jlong' to non-scalar type 'off_t' requested".
I'm getting a typedef redefinition error on two lines in MacTypes.h, in the following chunk of code:
#if __LP64__
typedef unsigned int UInt32;
typedef signed int SInt32;
#else
typedef unsigned long UInt32; // error here
typedef signed long SInt32; // error here
#endif
The Clang error points to the following previous definition, in CFBase.h (in CoreFoundation.framework):
#if !defined(__MACTYPES__)
#if !defined(_OS_OSTYPES_H)
typedef unsigned char Boolean;
typedef unsigned char UInt8;
typedef signed char SInt8;
typedef unsigned short UInt16;
typedef signed short SInt16;
typedef unsigned int UInt32; // previous definition is here
typedef signed int SInt32; // previous definition is here
typedef uint64_t UInt64;
typedef int64_t SInt64;
typedef SInt32 OSStatus;
#endif
...
This is very strange, since __LP64__ is apparently always true on the Mac platform, so why is that typedef even being evaluated? And why is there a path of compilation in which two OS-provided definitions are contradicting each other?
EDIT: Here is a screenshot of the errors in Xcode.
I've blanked out the path of the file that includes <Carbon/Carbon.h> since it contains the name of my client (the file is the same for both errors). The full path names below that are as follows (all contained within Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks):
Carbon.framework/Headers/Carbon.h:20
CoreServices.framework/Headers/CoreServices.h:18
CoreServices.framework/Frameworks/AE.framework/Headers/AE.h:20
CoreServices.framework/Frameworks/CarbonCore.framework/Headers/CarbonCore.h:27
CoreServices.framework/Frameworks/CarbonCore.framework/Headers/MacTypes.h:27
Update:
In my own code, just before #include <Carbon/Carbon.h> I've added the following:
#if __LP64__
#error Has LP64
#else
#error Doesn't have LP64
#endif
...and I'm getting the 'Doesn't have LP64' error, so this seems to be the root of the problem. However, when I compile the following in Sublime Text 2 (with SublimeClang)...
int main()
{
#if __LP64__
#error Has LP64
#else
#error Doesn't have LP64
#endif
return 0;
}
...I get "Has LP64". Doing a project text search for #define __LP64__ I can't find anything in my project, and when searching for __LP64__ it just comes up with a load of #ifs and #ifdefs. Does anyone know where this error could have come from?
In the end it turned out this problem was due to multiple installs of Xcode: I had recently installed Xcode 4.4 (from the App Store) and I still had an install of Xcode 3 somewhere. I solved this by running uninstall-devtools which removed Xcode 3, along with all its various paths in the Library and Developer folders. I'm not sure why conflicting installs of Xcode would cause a problem like this, but removing Xcode 3 solved it. I hope this helps anyone who has a problem like this - it's certainly not what I expected the problem to be.