Unexpected compile error on specific sockaddr_in variable name - c

As part of a function that receives a struct ifreq *ifr argument, if I declare struct sockaddr_in name;, the program compiles, but if I name the variable struct sockaddr_in ifr_addr;, it fails with the following error:
code.c:244:24: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘.’ token
struct sockaddr_in ifr_addr;
^
code.c:244:24: error: expected expression before ‘.’ token
Makefile:2: recipe for target 'all' failed
make: *** [all] Error 1
The ifreq struct is declared as below. I know that the struct has a field with the same name than the problematic variable. How is that a problem in C?
struct ifreq {
char ifr_name[IFNAMSIZ]; /* Interface name */
union {
struct sockaddr ifr_addr;
struct sockaddr ifr_dstaddr;
struct sockaddr ifr_broadaddr;
struct sockaddr ifr_netmask;
struct sockaddr ifr_hwaddr;
short ifr_flags;
int ifr_ifindex;
int ifr_metric;
int ifr_mtu;
struct ifmap ifr_map;
char ifr_slave[IFNAMSIZ];
char ifr_newname[IFNAMSIZ];
char *ifr_data;
};
};
http://man7.org/linux/man-pages/man7/netdevice.7.html

When you get an error like that, it almost invariably means that a header, in this case probably one of the system headers, has defined a macro with the same name as you chose for your variable, but with an expansion that is not valid as an identifier.
You wouldn't see a problem if the header defines:
#define ifr_addr pwr_address
You do see a problem if, as you note in a comment, the expansion (in include/uapi/linux/if.h, near line 258) is:
#define ifr_addr ifr_ifru.ifru_addr
The macro is meant to make it easier to access elements of a union without having to specify the union member name each time. At times like this, you find yourself asking — was it worth it? (I see this in the code base I work on daily — a lot. It's hard, sometimes, to work out what the code is accessing.)
Although it would be possible to use:
#undef ifr_addr
before defining your own variable with that name, doing so is treading on thin ice. It's best to accept that the name is preempted and use something else, annoying though it is. A possibility is to use ifr_srcaddr, to match/contrast ifr_dstaddr.

Related

error: expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ before ‘=’ token in struct

I'm getting the error when compiling with gcc -Wall -std=c99:
pokerhand.c:20:17: error: expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ before ‘=’ token
Card *cards = malloc(sizeof(Card)*5);
here is my code where the error is happening
typedef struct card
{
char suit;
char *face;
} Card;
typedef struct hand
{
Card *cards = malloc(sizeof(Card)*5);
char *result;
} Hand;
all I have before these structs is header includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
You can't write code inside a struct declaration. That is wrong.
I bet this would solve the error
typedef struct hand
{
Card *cards;
char *result;
} Hand;
And later you can allocate to it when you have proper variable declared with that type.
Also this would work
typedef struct hand
{
Card cards[5];
char *result;
} Hand;
If you think that each hand would contain 5 card every single time then yes you can add it like this.
In the first case you need to allocate the cards and then free it when you are done working with it.
You can't "do things" with the struct members when you define the struct.
So Card *cards = malloc(sizeof(Card)*5); makes no sense, and the compiler issues a diagnostic.
One solution is to build an init_card function, that takes a struct card* as an input parameter; and you perform your initialisation there. If you also build a corresponding free_card function you'll end up with something that scales up remarkably well.

struct producing errors in C

I am getting strange compilation errors from trying to create a struct in C.
Here is my code:
#define ALIGNMENT 8
/* rounds up to the nearest multiple of ALIGNMENT */
#define ALIGN(size) (((size) + (ALIGNMENT-1)) & ~0x7)
#define SIZE_T_SIZE (ALIGN(sizeof(size_t)))
#define BLK_HDR_SIZE ALIGN(sizeof(blockHdr))
typdef struct header {
size_t size;
blockHdr *next_p;
blockHdr *prior_p;
} blockHdr;
This is the error message:
mm.c:49:8: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘struct’
typdef struct header {
^
make: *** [mm.o] Error 1
I am baffled by this error. Is there something wrong with my code, or is there a more serious issue?
You have a typo in typdef. Next, you'll get an error about blockHdr not being defined.
The correct definition is:
typedef struct header {
size_t size;
struct header *next_p;
struct header *prior_p;
} blockHdr;
You can't use the typedef before it is declared. You have to use the actual structure name.
I think that that instead of
typdef struct header
it should be
typedef struct header

Setting up structs in C - giving strange errors

I have set-up structs like so in a C program:
typedef struct header block_header;
struct header {
size_t size;
block_header *next_pointer;
block_header *prev_pointer;
};
However, when I run any expression like the following:
int myinit()
{
block_header *p = init_heap_segment(BLOCK_HEAD_SIZE);
// etc etc
}
It gives me several errors for each function that it is declared in:
allocator.c: In function ‘myinit’:
allocator.c:37:38: error: ‘header’ undeclared (first use in this function)
allocator.c:37:38: note: each undeclared identifier is reported only once for each function it appears in
allocator.c: In function ‘function’:
allocator.c:67:2: error: unknown type name ‘header’
What is the problem with the way that it is set-up? How do I make these errors go away?
EDIT: Definition of:
#define BLOCK_HEAD_SIZE (ALIGN(sizeof(header)))
This is your problem
#define BLOCK_HEAD_SIZE (ALIGN(sizeof(header)))
There's no such type as header in your program, which is what the compiler is telling you. You have defined type struct header and you have defined a typedef name block_header for it. So choose whichever you prefer: either sizeof(struct header) or sizeof(block_header). But not sizeof(header).
In C++ language defining a struct header type would also introduce typename header into the program. But not in C. In C the type defined by struct header is called struct header - two words. It cannot be shortened to a mere header.
In your program, there is no such type called header. But you are using
#define BLOCK_HEAD_SIZE (ALIGN(sizeof(header))) // problem
It should be-
#define BLOCK_HEAD_SIZE (ALIGN(sizeof(struct header)))
or
#define BLOCK_HEAD_SIZE (ALIGN(sizeof(block_header)))
Whenever you are calculating size like this, make sure that you are using correct parameters!
Why not just do:
typedef struct block_header {
size_t size;
block_header *next_pointer;
block_header *prev_pointer;
}header;
and with that you can do:
header *p = init_heap_segment(BLOCK_HEAD_SIZE);
with a new declaration for init_heap_segment() where it returns 'header *' instead of 'struct block_header *'. Just much cleaner.

Trouble with compiling errors

I am getting some compilation errors I can't figure out, and although I'm sure they're quite stupid I can't find an answer that helps me much through other channels.
Problem 1: (These are a part of a TCP protocol)
error: ‘TH_SYN’ undeclared (first use in this function)
error: ‘TH_ACK’ undeclared (first use in this function)
tcp.tcph_flags = TH_SYN;
tcp.tcph_flags = TH_ACK;
Problem 2:
error: conversion to non-scalar type requested
const int one = 1;
char buffer[PCKT_LEN];
struct sockaddr_in sin;
struct ipheader ip;
struct tcpheader tcp;
ip = (struct ipheader) buffer; /* ERROR POINTS HERE */
tcp = (struct tcpheader) buffer + ip.iph_ihl *4; /* AND HERE */
Problem 3:
warning: assignment makes integer from pointer without a cast
case 'i': dip = inet_addr(optarg);
dstip = (optarg); /* ERROR POINTS TO THIS LINE */
break;
Now I hope I've copied enough relevant information on the errors for you to be able to help, but if I've left something out let me know. For problem 1, I believe I am missing a header file of some sort but I don't know which. Problem 2 and 3 are pointer issues, but I'm not sure why they aren't correct. Thanks in advance :)
For the first problem, include the header defining TH_SYN and TH_ACK. On my system it's netinet/tcp.h
For the second problem, turn ipheader and tcpheader into pointers
For the third problem I think you need a strtoul but I'm unsure
For problem 1, you need
#include <netinet/tcp.h>
For problem 2, struct ipheader should be struct ipheader * in both your declaration and cast, as well as struct tcpheader should be struct tcpheader *
For problem 3, optarg is a pointer, and needs to be dereferenced, so refer to it as *optarg

warning: improper pointer/integer combination: op "="

I compile a C program in Solaris and get this warning.
line 68: warning: improper pointer/integer combination: op "="
My code contains
struct cmsghdr *cmsg;
Line 68 is
cmsg = CMSG_FIRSTHDR(&msg);
The structure cmsghdr and CMSG_FIRSTHDR is defined in socket.h as
#define CMSG_FIRSTHDR(m)
--
--
struct cmsghdr {
socklen_t cmsg_len;
int cmsg_level;
int cmsg_type;
};
I have included socket.h in my code. But still I get this error.
It is possible that the CMSG_FIRSTHDR macro doesn't do proper typecasting, so you have to do it yourself:
cmsg = (struct msghdr *) (CMSG_FIRSTHDR(&msg));
It might also be that there is some improper casting inside the macro itself, in which case there is nothing you can do, as it's in a system header.
please check what type SOL_SOCKET is. It needs to be int.
Change the type of the filed "cmsg_level" in your struct, if it dosen't match.
I guess SOL_SOCKET is a pointer, maybe int*

Resources