Home > Mobile >  GNUC for ARM. Why would a #define need a defined type?
GNUC for ARM. Why would a #define need a defined type?

Time:09-10

I'm trying to build the WolfSSL, using GNU-C 7.3.1 for ARMv7.

I am getting an error where I've never seen one before. In this code fragment for Wolfio.h:

#ifndef WOLFSSL_NO_SOCK
#ifndef XSOCKLENT
    #ifdef USE_WINDOWS_API
        #define XSOCKLENT int
    #else
        #define XSOCKLENT socklen_t
    #endif
#endif

/* Socket Addr Support */
#ifdef HAVE_SOCKADDR
#ifndef HAVE_SOCKADDR_DEFINED

The 6th line in the above fragment:

#define XSOCKLENT socklen_t

Gives the error:

wolfio.h:383:31: error: unknown type name 'socklen_t'; did you mean '__socklen_t'?

Huh...?? why would a #define assignment need a type that exists?

I tried an alternate test in a dummy file of a different project, with the following. Neither of which are defined:

#define MYTYPE  SOMETHING

And I received no error.

Because for decades I've believed that #defines are just preprocessor replacements. And doesn't analyze any of the source. My test in the dummy file confirms that belief.

So, somehow inside this large project, the GNU compiler got into it's head that a #define is really just a typedef?? And the RHS of the #define is required to be a defined type?

Is there a compiler or #pragma setting that makes it think this?

The project is for a TI ARM device, using their Code Composer studio

For reference, the compile args are (without my includes):

-mcpu=cortex-a8 
-march=armv7-a 
-mtune=cortex-a8 
-marm 
-mfloat-abi=hard 
-mfpu=neon 
-Dam3359 
-Dam335x 
-Dxdc_target_types__=gnu/targets/std.h 
-Dxdc_target_name__=gnu/targets/arm/A8F 
{includes}  
-Ofast 
-Wall 
-specs="nosys.specs"

Any advice is appreciated.

CodePudding user response:

#define does not care about any types as preprocessor only textually replaces strings (more precise tokens) and does not know anything about the C language and types.

The error is generated by the C compiler when the C file after the preprocessing was compiled (ie all XSOCKLENT tokens were replace by the socklen_t token).

CodePudding user response:

I think this is just a misunderstanding caused by the compiler's error message format.

You are quite right that there is nothing wrong per se with defining a macro that expands to a nonexistent type. The issue is almost certainly that some other part of your program includes this header and declares a XSOCKLENT my_var; without having included <sys/socket.h> to get the socklen_t type defined. That would account for the unknown type name error.

What's confusing you is that the line number referenced by the error message is the definition of the XSOCKLENT macro. This is a feature; the idea being that when code resulting from macro expansion causes an error, then more often than not, the bug is in the way the macro was defined. Here, that happens to not be the case. But if you look at the next bit of the compiler output, you ought to see the file and line where the macro was used. That should be the file that needs to be including <sys/socket.h>. (Or maybe you want Wolfio.h to include it; you'll have to see what makes the most sense.)

Example: with the file

#define FOO djewiodjwoidjeiwojdiwe

FOO x;

GCC 11 outputs:

foo.c:1:13: error: unknown type name ‘djewiodjwoidjeiwojdiwe’
    1 | #define FOO djewiodjwoidjeiwojdiwe
      |             ^~~~~~~~~~~~~~~~~~~~~~
foo.c:3:1: note: in expansion of macro ‘FOO’
    3 | FOO x;
      | ^~~

Note the first message points to line 1, where the macro is defined, and the second part of the message points to line 3, where it is used. If one isn't what you are looking for, then try the other.

  • Related