1

I have this header that contains an array that I need in multiple places in my code:

protected_dirs.h

#ifndef PROTECTED_DIRS
#define PROTECTED_DIRS

extern int PROTECTED_DIRS_COUNT;

extern char* PROTECTED_DIRS[];
extern char* PROTECTED_DIRS_PASSWORDS[];

#endif

I additionally have this file to initialize the values:

protected_dirs.c

#include <protected_dirs.h>

const int PROTECTED_DIRS_COUNT = 2;

const char* PROTECTED_DIRS[] = {"target", "IOS_Project"};
const char* PROTECTED_DIRS_PASSWORDS[] = {"1234", "1111"};

I then try to use the code in a file called ios_cd.c:

int checkPasswordForRoom(char* targetDir, char* password){
    int accessGranted = 0;
    int directoryRestricted = 0;
    for (int i = 0; i < PROTECTED_DIRS_COUNT; i++) {
        if (strcmp(PROTECTED_DIRS[i], targetDir) == 0) {
            directoryRestricted = 1;
            if (strcmp(PROTECTED_DIRS_PASSWORDS[i], password) == 0) {
                accessGranted = 1;
            }
        }
    }

    if (directoryRestricted) {
        return accessGranted;
    } else {
        return 1;
    }

}

This seemed very straightforward to me, but then I got this error, which confused me a lot. At the beginning I had a local variable in my checkPasswordForRoom function, but then realized I would need the list of protected directories elsewhere as well. I created a header with a small c file to initialize the values, but all of a sudden my code will not compile anymore.

This is the output I get from the compiler which makes no sense to me at all:


gcc -Iutils -Imodules -Wall -Wextra -c utils/ios_cd.c -o build/utils/ios_cd.o
In file included from utils/ios_cd.c:10:
utils/protected_dirs.h:6:28: error: expected identifier or ‘(’ before ‘[’ token
    6 | extern char* PROTECTED_DIRS[];
      |                            ^
utils/ios_cd.c: In function ‘checkPasswordForRoom’:
utils/ios_cd.c:45:34: error: expected expression before ‘[’ token
   45 |         if (strcmp(PROTECTED_DIRS[i], targetDir) == 0) {
      |                                  ^
make: *** [Makefile:11: build/utils/ios_cd.o] Error 1

It almost seems as if the compiler expected a function definion, since it wants an identifier or a (... What is wrong here, how can I fix this?

EDIT:

This is funny... I tried changing the name, and now the compilation error disappears. What is special about the PROTECTED_DIR name, a quick ddg search didn't show me anything meaningful except my own question...

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
monamona
  • 1,195
  • 2
  • 17
  • 43
  • I guess that the types are not the same. One has `const`, second not. Or check this one https://stackoverflow.com/questions/14977058/extern-const-char-const-some-constant-giving-me-linker-errors. – Andy Mar 18 '23 at 20:54
  • See my edit, that does not seem to explain this behaviour – monamona Mar 18 '23 at 20:56
  • I've tried compiling this on Godbolt with a number of different C++ and C compilers, not seeing this error. Which toolchain are you using? See https://godbolt.org/z/ra78o9x5P – Den-Jason Mar 18 '23 at 20:58
  • @Den-Jason Since the error originated in a name conflict within the header, the code you entered into the godbolt is not quite the same and thus not able to reproduce the error. Unfortunate in this case, see the answers down below :) – monamona Mar 18 '23 at 21:13

2 Answers2

3

This is your problem:

#ifndef PROTECTED_DIRS
#define PROTECTED_DIRS

You’ve defined PROTECTED_DIRS to be a macro which expands to nothing. Fix it by using a different name. I like to use _H on the end.

#ifndef PROTECTED_DIRS_H
#define PROTECTED_DIRS_H

Alternatively, you could use #pragma once:

#pragma once

This is mostly a matter of style. The #pragma once is not, strictly speaking, portable—and it does not work if you can include the same file via different paths—but not everyone cares about those things.

Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
1

I am sorry. I was not attentive. There is the directive

#define PROTECTED_DIRS

with the same name as the name of the array that produces the error.

Either rename the defined name in the directive or the name of the array.

Also you need in all declarations of the variables either to use the qualifier const or to remove it.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335