3

I have created a simple semaphore initialization example for demo purpose:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdlib.h>

int init_semaphore(int semid, int semnum, int initval)
{
    union semun pack;
    pack.val = initval;
    return semctl(semid,semnum,SETVAL,pack);
}

But I am getting the error:

error: aggregate ‘init_semaphore(int, int, int)::semun pack’ has incomplete type and cannot be defined

I am not able to understand why the compiler is throwing the error. The headers are also included properly.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
Naveen
  • 7,944
  • 12
  • 78
  • 165
  • 2
    `man semctl`: *[...]When there are four, the fourth has the type union semun. The calling program must define this union as follows: union semun { int val; /* Value for SETVAL */ struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ unsigned short *array; /* Array for GETALL, SETALL */ struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */ };* – EOF Jun 01 '16 at 20:09
  • @EOF - that's an answer, not a comment (and now AndrewHenle has it as an answer) – KevinDTimm Jun 01 '16 at 20:13

1 Answers1

4

You have to explicitly declare union semun yourself.

Per the POSIX standard for semctl():

The semctl() function provides a variety of semaphore control operations as specified by cmd. The fourth argument is optional and depends upon the operation requested. If required, it is of type union semun, which the application shall explicitly declare:

union semun {
    int val;
    struct semid_ds *buf;
    unsigned short  *array;
} arg;

Per the Linux man page:

This function has three or four arguments, depending on cmd. When there are four, the fourth has the type union semun. The calling program must define this union as follows:

   union semun {
       int              val;    /* Value for SETVAL */
       struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
       unsigned short  *array;  /* Array for GETALL, SETALL */
       struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                   (Linux-specific) */
   };
Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • Do you know what the rationale is for making the program declare `union semun`, rather than simply having it declared in a standard header like ``? – Nate Eldredge Jun 01 '16 at 21:06
  • @NateEldredge The only reason I can think of is that by the time the call was standardized, too much legacy code would have been broken. – Andrew Henle Jun 02 '16 at 10:33