Aspell won't build on OS X 10.9 (Mavericks) - macports

It fails thus:
./common/errors.hpp:17:36: error: redefinition of 'aerror_other' with a different type: 'const acommon::ErrorInfo *const' vs 'const struct AspellErrorInfo *const'
I've seen this error mentioned several times, but I've not seen any fixes.
I suppose I could install Fink or MacPorts, but my experience with both of those has been mixed (and frustrating), and it seems like overkill for just one program. Is there a way to get aspell to build, or is Fink or MacPorts the only practical option? Which will cause fewer problems, Fink or MacPorts?

The definition of those externs is not for C++ - surround the entire block with these preprocessor tags in interfaces/cc/aspell.h:
#ifndef __cplusplus
extern const struct AspellErrorInfo * const aerror_other;
...snip...
extern const struct AspellErrorInfo * const aerror_invalid_expression;
#endif

The answer by #lotsoffreetime works but needs some clarification.
Basically, you have to edit the interfaces/cc/aspell.h file by adding
#ifndef __cplusplus
before the list of "extern" errors, which starts with:
extern const struct AspellErrorInfo * const aerror_other;
and add
#endif
at the end of the list, after it reads
extern const struct AspellErrorInfo * const aerror_invalid_expression;

Related

Forward declaration issue, two compilers

I've been developing in C using eclipse as my IDE in my virtual machine with ubuntu, I've made some progress and I wanted to test them in the real product which is an embedded system using powerpc.
In order to compile that program for our product I use Code::Blocks in Windows but the compiler is a powerpc version of the gcc.
The same code is giving me an error in the powerpc version that doesn't appear in the ubuntu version.
I have two header files gral.h and module_hand.h as follows:
The gral.h file:
#ifndef HEADERS_GRAL_H_
#define HEADERS_GRAL_H_
#include "module_hand.h"
typedef struct PROFILE
{
module_t mod; // this one comes from module_hand.h
int var1; // some other random variables
} profile_t;
#endif /* HEADERS_GRAL_H_ */
The module_hand.h is defined as follows
#ifndef HEADERS_MODULE_HAND_H_
#define HEADERS_MODULE_HAND_H_
#include <stdint.h>
#include "gral.h"
typedef struct PROFILE profile_t;
typedef struct module
{
char name[30]; // name of module
char rev[30]; // module revision
char mfr[30]; // manufacturer
} module_t;
int Mod_Init(profile_t *profile);
/* some other random functions */
#endif /* HEADERS_MODULE_HAND_H_*/
As you'll see, I don't use the PROFILE struct in the module struct, But I declare it forward to use it in the declaration of the Mod_Init function
This gives me a Error: redefinition of typedef 'profile_t'
and error: previous declaration of 'profile_t' was here
If I remove the forward declaration the error is Error: parse error before '*' token
where the line number is the line of the function declaration.
My doubt is what am I missing, and why gcc in Ubuntu does compile it with no problem.
Your powerpc compiler is enforcing the C99 rule that
If an identifier has no linkage, there shall be no more than one
declaration of the identifier (in a declarator or type specifier) with
the same scope and in the same name space, except for tags as
specified in 6.7.2.3.
(C99 6.7/3)
Your Linux compiler is observing the relaxed version of that rule that was introduced in C11:
If an identifier has no linkage, there shall be no more than one
declaration of the identifier (in a declarator or type specifier) with
the same scope and in the same name space, except that:
a typedef name may be redefined to denote the same type as it currently does, provided that type is not a variably modified type;
tags may be redeclared as specified in 6.7.2.3.
(C11 6.7/3; also C17 6.7/3)
Supposing that the compilation options are the same, the behavior difference surely arises from using different versions of GCC. More recent versions default to more recent versions of the language.
You could try adding -std=gnu11 or -std=c11 to the command-line options (for both targets) to try to get consistency. If your powerpc version of GCC is too old to accept those then you really need to update to a newer version.
Note also, however, that you don't need to have this problem in the first place. Given that module_hand.h includes gral.h, the former has no need whatever to redefine a typedef that the latter already defines.
Moreover, the fact that these two headers each include the other is a strong suggestion that they ought to be combined into one. Multiple-inclusion guards prevent an actual loop, but they are not an adequate solution.
In the gral.h header file, you define profile_t using typedef, then you redefine profile_t with another typedef in module_hand.h. You should just define the struct PROFILE in gral_h and include gral.h in module_hand.h.
gral.h:
#ifndef HEADERS_GRAL_H_
#define HEADERS_GRAL_H_
#include "module_hand.h"
typedef struct PROFILE {
module_t mod; // this one comes from module_hand.h
int var1; // some other random variables
} profile_t;
#endif /* HEADERS_GRAL_H_ */:
module_hand.h:
#ifndef HEADERS_MODULE_HAND_H_
#define HEADERS_MODULE_HAND_H_
#include <stdint.h>
typedef struct module
{
char name[30]; // name of module
char rev[30]; // module revision
char mfr[30]; // manufacturer
} module_t;
int Mod_Init(struct PROFILE *profile);
/* some other random functions */
#endif /* HEADERS_MODULE_HAND_H_*/
Well I read your answers and comments and decided to try another approach.
As some of you said, I had some kind of recursion, I wanted to keep every structure within its respective header file, but now, I dropped the idea and merged the structures in one file only.
My new approach:
Gral.h
#ifndef HEADERS_GRAL_H_
#define HEADERS_GRAL_H_
typedef struct module
{
char name[30]; // name of module
char rev[30]; // module revision
char mfr[30]; // manufacturer
} module_t;
typedef struct PROFILE {
module_t mod; // this one comes from module_hand.h
int var1; // some other variables
} profile_t;
#endif /* HEADERS_GRAL_H_ */:
Module.h
#ifndef HEADERS_MODULE_HAND_H_
#define HEADERS_MODULE_HAND_H_
#include <Gral.h>
int Mod_Init(profile_t *profile);
/* some other functions */
#endif /* HEADERS_MODULE_HAND_H_*/
And when any other structure comes up, I'll declare it in Gral.h and include the header file.
Regarding the compilers, they aren't the same version. The powerpc is quite old now. That would explain the powerpc compilation errors.
Thank you again.

Why can't I have an inner structure when two files include each other?

For context, I'm writing an operating system:
I have a struct vt_device_s and a struct __vt_device_s which is architecture specific and lives inside of vt_device_s like so:
struct
vt_device_s
{
struct __vt_device_s __device;
size_t cursor_x;
size_t cursor_y;
};
Now for the architectural struct:
struct
__vt_device_s
{
uint16_t *memory;
size_t memory_len;
};
The header <dev/vt.h> knows about __vt_device_s defined in <sys/_vt.h> because it is included, yet I get this error:
error: field '__device' has incomplete type
48 | struct __vt_device_s __device;
|
I realise this is because both files rely on each other (the whole conflict is caused by _vt.c including _vt.h including vt.h including _vt.h) but I don't understand how it is a compile problem. I have include guards in both files!
PS: I understand this would be a non-issue if I used a pointer but as it's an operating system, this driver needs to function before paging is set up (that is, malloc and free don't exist yet).
Here are the three files in question:
dev/vt.h
#ifndef _DEV_VT_H_
#define _DEV_VT_H_ 1
#include <stddef.h>
#include <sys/_vt.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct
vt_device_s
{
struct __vt_device_s __device;
size_t cursor_x;
size_t cursor_y;
};
void vt_init(struct vt_device_s *);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _DEV_VT_H_ */
sys/_vt.h
#ifndef _I386__VT_H_
#define _I386__VT_H_ 1
#include <stddef.h>
#include <stdint.h>
#include <dev/vt.h>
#define __VT_WIDTH 80
#define __VT_HEIGHT 25
#define __VT_MEMOFF 0xb8000
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct
__vt_device_s
{
uint16_t *memory;
size_t memory_len;
};
void __vt_init(struct vt_device_s *);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _I386__VT_H_ */
sys/_vt.c
#include <sys/_vt.h>
void
__vt_init(struct vt_device_s *device)
{
device->__device.memory = (uint16_t *) __VT_MEMOFF;
device->__device.memory_len = __VT_WIDTH * __VT_HEIGHT;
}
Your double include guards prevent the one file from including itself when it is re-included by the other. The only way to fix this is you have got to break the cycle. Decide which header is "higher" and will include the "lower" and don't try to include the higher one from the lower one. The lower one must be valid on its own.
The reason for this is that the pre-processor has to transform multiple files into one linear sequence of lines for the compiler. The compiler has to see one set of file contents before the other.
If you have cyclic includes like this you make it up to the final user of the code which one comes first. If they include file A, then it will include file B, which will try to include file A again but it will be prevented by the include guards, so the contents of B will be parsed first. On the other hand if the final user includes B first, then the contents of A will be seen first by the compiler.
So if you leave it like it is, then it is effectively random which file gets included first. If you break the cycle, you get to decide yourself which is included first.
Once you have decided, you can fix the compiler errors about incomplete types by making whichever file you choose to put first able to stand on its own and then letting the one that is second use definitions from the first.

Automatically detect if need to add a "const" qualifier in function parameters

I have written a PMPI profiling library that intercepts many MPI functions.
On my local machine I have an OpenMPI installation and some function parameters have a const qualifier, for example:
int PMPI_Gather(const void *sendbuf, int sendcount, ...)
So naturally, my PMPI library also has those const qualifiers in corresponding hook functions. However, the remote machine where I'm often running stuff has an MPI installation in which function parameters in mpi.h don't have const qualifiers, so when I compile my library I get a whole bunch of warnings that the function declaration is incompatible. Of course, I can just ignore the warnings, suppress them or manually delete the const qualifier.
I wonder if there is a more graceful way to handle the situation, if it's possible to detect somehow if function declarations in mpi.h have or haven't const parameters and automatically add or remove the const qualifier in the profiling library code during compilation, or perhaps it could be some kind of a configuration feature.
const-correctness for the C bindings, i.e. const pointers for IN parameters, was added in MPI 3.0. You can handle this the following:
#if MPI_VERSION >= 3
#define MPI_CONST const
#else
#define MPI_CONST
#endif
int PMPI_Gather(MPI_CONST void *sendbuf, int sendcount, ...)
Note: you can see the changes easily in section A.2 C Bindings of the "diff to 3.0" version of the standard.
An alternative to #ifdef ... is to simply check which type the function got:
typedef int PMPI_Gather_noconst (void *sendbuf, int sendcount, ...);
typedef int PMPI_Gather_const (const void *sendbuf, int sendcount, ...);
if( _Generic(PMPI_Gather, PMPI_Gather_noconst*:true, PMPI_Gather_const*:false) )
{
PMPI_Gather_noconst* stuff;
...
}
else
{
PMPI_Gather_const* stuff;
...
}
Usually in this situations where a variable or defines can be defined in multiple places is used #ifdef or #ifndef.
You would have something like:
#ifndef _YOU_CONSTANT
#define _YOU_CONSTANT
#endif

error: expected ')' before '*' token

I receive this error when compiling my code and got absolutely no idea after trying out for an hour.
This is the file which causes the error os_memory_strategies.h:
#ifndef _OS_MEMORY_STRATEGIES_H
#define _OS_MEMORY_STRATEGIES_H
#include "os_mem_drivers.h"
#include "os_memheap_drivers.h"
#include "os_process.h"
#include "defines.h"
#include <stdint.h>
MemAddr os_Memory_FirstFit (Heap *heap, uint16_t size);
#endif
The line
MemAddr os_Memory_FirstFit (Heap *heap, uint16_t size);
causes the error. As I understand "Heap" is unknown to this point. The struct Heap is defined in os_memheap_drivers.h which is included here. The struct looks like this:
typedef struct Heap{
prog_char *const name;
MemDriver *const driver;
AllocStrategy allocStrat;
Memory const memory;
}Heap;
Using AVRStudio and all the files are in the same directory.
The most typical reason for this is circular header inclusion. You include os_memheap_drivers.h into your os_memory_strategies.h (as we can see above). But apparently you also directly or indirectly include os_memory_strategies.h into os_memheap_drivers.h as well.
The include guards will naturally "resolve" this circular inclusion is some unpredictable way, i.e. one of these files will end up being included first and the other will end up being included second. In your case os_memory_strategies.h ended up being included first, which is why it does not recognize Heap as type name.
Circular header inclusion never works and never achieves anything. Get rid of it, i.e. make sure os_memory_strategies.h in not included into os_memheap_drivers.h.

DLL function not exported: Unable to find an entry point named TestFunc

I'm busy getting to know a tiny bit of C/C++, and interop with C#. I've checked several examples of creating a simple Win32 DLL and using this from C#, but when I try and call into my DLL, I get the runtime error: "Unable to find an entry point named TestFunc". My DLL looks like this, and I created it from a Win32 DLL project, with the empty project option:
Header:
__declspec(dllexport) int TestFunc(char *, char *, char *);
Code file:
#include "stdafx.h"
#include "TestLib.h"
__declspec(dllexport) int TestFunc(char *arg1, char *arg2, char *arg3)
{
char str1[] = "Brady Kelly";
char str2[] = "Hello World";
char str3[] = "1234567890";
strcpy(arg1, str1);
return 128;
}
What am I doing wrong?
Is your function compiled using C or C++ bindings? You don't specify, but it looks to me like there is a possibility that you are using the C++ compiler - the compiler uses very different name mangling from the C compiler and you will not be able to find the name "TestFunc" as simply as if you were using the C compiler or using C name mangling rules.
To simply tell the C++ compiler to use C name mangling rules, use this in the header file:
extern "C"
{
__declspec(dllexport) int TestFunc(char *, char *, char *);
}
Also, you only need the declspec in front of the function declaration (in the header file), not the definition. A useful tool for examining what is exported from the DLL, and what the DLL depends on is Dependency Walker.
Actually since you have tagged this question as C, I'd suggest a minor change from what 1800 INFORMATION's solution:
#ifdef __cplusplus
extern "C" {
#endif
#ifdef EXPORT_MODE
#define METHODTYPE __declspec(dllexport)
#else
#define METHODTYPE __declspec(dllimport)
#endif
#ifdef __cplusplus
}
#endif
/*! _The_ method */
METHODTYPE int TestFunc(char *, char *, char *);
This will let you use the same header both in clients' code and your code.
NB: Dependency Walker is no longer bundled with VS2008. You must download it if you are using VS2008.

Resources