0

I need a hand with this: I have .c file with a typedef struct in it and when I build the proyect it appears the next error in my header file: "unknown type name 'buffer'" ('buffer' is the name of my struct). I've been trying different solutions posted in this site but nothing seems to work.

I tried adding in the header file the next line:

typedef struct Buffer Buffer;

this solves the "unknown type name 'Buffer'" error but two other appears in the .c file: "multiple definition of `init_buffer'" and "first defined here" (pointing to the .c file).

The code I have in the header file looks like:

#include <stdbool.h>

#ifndef INC_CIRCULAR_BUFFER_H_
#define INC_CIRCULAR_BUFFER_H_

typedef struct Buffer Buffer;

void init_buffer(buffer *q,uint8_t max_size);

and my .c file looks like:

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <circular-buffer.h>
#define BUFFER_EMPTY -1
#define MAX_SIZE 64

typedef struct Buffer{
    uint8_t *values;
    uint8_t head,tail,num_entries,size;
}Buffer;

void init_buffer(Buffer *q,uint8_t max_size){
//Here goes the function body
}
  • Do you `#include` the *source* file anywhere? – Some programmer dude Mar 14 '23 at 16:21
  • 1
    Is `buffer` vs `Buffer` between the declaration and definition just a typo? – Brian61354270 Mar 14 '23 at 16:32
  • By the way, in the C source file you don't need to `typedef` the structure. If you include the header file it will be done there. – Some programmer dude Mar 14 '23 at 16:54
  • Please take some time to read [the help pages](http://stackoverflow.com/help), take the SO [tour], read [ask], as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). This will help you improve your questions. – Some programmer dude Mar 14 '23 at 17:00
  • There is no such thing as a "typedef struct". A "typedef" and a "struct" are separate things, sometimes used together and other times not. – John Bollinger Mar 14 '23 at 17:15
  • In fact, I think beginning C students would do well to consider `typedef` an advanced topic, to be reserved for when they have a bit more experience. It is sometimes a convenience, but never a necessity, and it can obfuscate at least as easily as it can clarify. – John Bollinger Mar 14 '23 at 17:18
  • Thanks, i will look for another path for what I need to do – JULIO JOSE ALIAGA Mar 14 '23 at 17:24

2 Answers2

0

In the header you have:

void init_buffer(buffer *q,uint8_t max_size);

However, buffer is not defined. It should be capitalized as:

void init_buffer(Buffer *q, uint8_t max_size);

A few other problems:

  1. The typedef is unnecessary in the .c file because it was already typedef'd in the .h file.
  2. The header file is missing an #endif.
  3. The header doesn't include stdint.h for uint8_t.

Here are versions of the .h and .c file that compile with gcc -c circular-buffer.c:

/** file: circular-buffer.h **/
#ifndef INC_CIRCULAR_BUFFER_H_
#define INC_CIRCULAR_BUFFER_H_
#include <stdint.h>

typedef struct Buffer Buffer;

void init_buffer(Buffer* q, uint8_t max_size);

#endif
/** file: circular-buffer.c **/
#include "circular-buffer.h"

struct Buffer {
  uint8_t* values;
  uint8_t head;
  uint8_t tail;
  uint8_t num_entries;
  uint8_t size;
};

void init_buffer(Buffer* q, uint8_t max_size) {
  //Here goes the function body
}
grencez
  • 3
  • 2
0

Compare this declaration from your header ...

void init_buffer(buffer *q,uint8_t max_size);

... to this one from your .c file:

void init_buffer(Buffer *q,uint8_t max_size)

C identifiers are case sensitive, so regardless of anything else, it is of immediate concern that those don't match with respect to the spelling of the type of their first parameters.

The typedef declared in the header ...

typedef struct Buffer Buffer;

... supports the latter, but not the former.

Note well that as I said in comments, typedef and struct are distinct things. The struct keyword is used in declaring and referencing structure types. The typedef keyword is used to declare an alias for a type name. These can be used together, and they can be used separately, but IMO, it is usually better not to use typedef at all. Example:


circular-buffer.h

#ifndef INC_CIRCULAR_BUFFER_H_
#define INC_CIRCULAR_BUFFER_H_
#include <stdint.h>

struct Buffer;

void init_buffer(struct Buffer *q, uint8_t max_size);
#endif

circular-buffer.c

#include <stdint.h>
#include "circular-buffer.h"

struct Buffer {
    uint8_t *values;
    uint8_t head, tail, num_entries, size;
};

void init_buffer(struct Buffer *q, uint8_t max_size) {
    //Here goes the function body
}

If you insist on using typedef then best practice would be to choose one spelling / capitalization. It would be most conventional to choose the structure tag for that (and C++ gives you that effect automatically), but in practice, you can choose any type alias you want. Or even multiple.

But note that typedef can get a little sticky. Historically, it was not allowed to declare the same typedef multiple times in the same translation unit, even if the definitions were identical. That's relaxed in the current version of the language, but your compatibility with older compilers is improved if you avoid, say, having the same typedef in both the .c file and the header (supposing that the former is going to #include the latter).

Recommended typedef usage:

circular-buffer.h

#ifndef INC_CIRCULAR_BUFFER_H_
#define INC_CIRCULAR_BUFFER_H_
#include <stdint.h>

struct Buffer;

typedef struct Buffer Buffer;

void init_buffer(Buffer *q, uint8_t max_size);
#endif

circular-buffer.c

#include <stdint.h>
#include "circular-buffer.h"

struct Buffer {
    uint8_t *values;
    uint8_t head, tail, num_entries, size;
};

void init_buffer(Buffer *q, uint8_t max_size) {
    //Here goes the function body
}

John Bollinger
  • 160,171
  • 8
  • 81
  • 157