0

I added two files to a Xcode 5.1 vanilla single view project:

table.h

struct group {
    int size;
};

table.c

#include "table.h"

and got this error:

Semantic issue
table.h:2:8: Redefinition of 'group'

"Previous definition" is:

iOS 7.1 > usr/include > grp.h

I am wondering why this grp.h is automatically included in my project. How can I not include it?

ohho
  • 50,879
  • 75
  • 256
  • 383
  • Have you tried renaming the struct? – Milo Mar 17 '14 at 01:35
  • Renaming the struct kills the error. Unfortunately the `struct group` is from another library. The error did not show up before I upgraded my existing project to iOS 7.1/Xcode 5.1. – ohho Mar 17 '14 at 03:09

3 Answers3

5

grp.h is one of the standard Unix-level files which defines some of the basic data structures; in this case, struct group is what gets returned by low-level C functions that deal with user permissions.

As for the question of why it's included in your project: When you create a new project in Xcode, it creates an include file that implicitly gets included in every .m or .c file in your project. In the project I just created to try this out, it's in the file browser in a group called Supporting Files, named something like [project]-Prefix.pch. Mine has the following contents:

#import <Availability.h>

#ifndef __IPHONE_5_0
#warning "This project uses features only available in iOS SDK 5.0 and later."
#endif

#ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
#endif

That second to last line, #import <Foundation/Foundation.h>, then includes all the built-in Objective-C objects like NSObject, NSArray - and a bunch of things that work with the filesystem, and therefore need to be able to deal with permissions and group membership. One of those is then including grp.h.

So, back to your question - you can change your .pch file to not include Foundation/Foundation.h, and then manually include it wherever you need it.

But that will end up slowing down all your builds. The .pch file here is special; Xcode compiles it once and saves it in a binary format, so it doesn't have to parse the many thousands of lines of C code it expands to for every file you build.

My advice? Name your structure something else.

dpassage
  • 5,423
  • 3
  • 25
  • 53
  • 1
    Unfortunately the `struct group` is from another library. The error did not show up before I upgraded my existing project to iOS 7.1/Xcode 5.1. – ohho Mar 17 '14 at 03:08
1

Normally of course it would be easier to change the naming of your struct, but as it comes from another library, here is my solution for you.

Turns out that if you allow your .pch file to include any of header files from iOS 7.1 > /usr/include then it will reference (include?) many more, including grp.h which causes the problem in your project.

So for example, if your .pch files contains this:

#import <Availability.h>

Then grp.h will cause the conflict.

If you comment out this line (and don't include any other headers from "iOS 7.1 > usr/include") then your project will compile.

As a test you can comment out <Availability.h> and add #import <cpio.h> and the result will be the same (although cpio.h is very small and don't reference any other header files).

I am not that good at understanding internals of compilation, so I can't explain why this happens but I traced down the issue to this file: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk/usr/include/module.map which seems to group together various Darwin header files.

Both iOS 7.0 and iOS 7.1 have this file while iOS 6.0 doesn't (which may explain why the same code worked on earlier iOS versions).

The good news is that although you need to remove /usr/include headers from your *.pch file, you can still include them in files where you actually need them and it won't break the compilation. That's probably because although the grp.h will eventually be included in those files, it won't be included in your table.c

Andris Zalitis
  • 2,369
  • 18
  • 18
0

grp.h has already declared a struct named 'group', so you just need to rename your 'group' struct and everything will be ok. (for example 'my_group')

ziggear
  • 886
  • 7
  • 22