I am trying to implement an array implementation of a stack. I am new to stack and I have tried to implement the push operation in c, and here is my code:
#include "stack.h"
/**
* push_arr_stack - pushes an element to the stack
* @n: The number that will be pushed to the stack
*
* Return: It returns nothing
*
*/
void push_arr_stack(int n)
{
top = top 1;
stack_arr[top] = n;
}
Here is my header file:
#ifndef STACK_H
#define STACK_H
#define MAX 4
extern int stack_arr[MAX];
extern int top = -1;
void push_arr_stack(int n);
#endif
And I have tried the push operation using the following test function:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include "stack.h"
/**
* main - Entry point for my program
*
* Return: On success, it returns 0,
* On error, it returns -1
*/
int main(void)
{
push_arr_stack(7);
return (0);
}
But I get the following error,
gcc -Wall -Werror -Wextra -pedantic -std=gnu89 main.c 0-push_arr_stack.c
In file included from main.c:4:
stack.h:6:12: error: ‘top’ initialized and declared ‘extern’ [-Werror]
6 | extern int top = -1;
| ^~~
cc1: all warnings being treated as errors
In file included from 0-push_arr_stack.c:1:
stack.h:6:12: error: ‘top’ initialized and declared ‘extern’ [-Werror]
6 | extern int top = -1;
| ^~~
cc1: all warnings being treated as errors
I need the top variable to track which index is the top of the stack, but it is giving me the error that top
is initialized and declared. How can I make it so I can initialize top
to -1
CodePudding user response:
Either those variables should be local to stack.c
or to the caller. They should not be declared at file scope (outside any function). By declaring something extern
, you state that "this is allocated elsewhere". But you never actually allocate it elsewhere, hence the problems. Also, since it is allocated elsewhere, the initialization has to be placed elsewhere too.
However, using extern
like this is very bad practice, since it creates global variables and spaghetti code, where one variable is shared across multiple files even though it shouldn't.
Instead you could place all those variables inside a struct. For beginner-level applications it is probably sufficient to just do like this:
// stack.h
typedef struct
{
int stack_arr[MAX];
int top;
} stack;
void stack_init (stack* s);
And then:
// stack.c
void stack_init (stack* s)
{
/* default initialization here */
s->top = -1;
}
Now the caller of your code can include stack.h, declare a variable stack my_stack;
and then call your functions like stack_init(&my_stack);
.
For professional applications, the above may not be considered good enough, since it violates the best design practice known as private encapsulation. The caller gets access to internal variables of the struct even though they shouldn't. In such cases one could implement opaque types to fix this: How to do private encapsulation in C?
CodePudding user response:
The header file is included in two translation units: with main and with the function definition. So the variable top
is defined twice.
In the header file just declare the variable
extern int top;
and in main define it like
int top = -1;
before the function main after the header.
Pay attention to that a variable declared in a file scope with the storage class specifier extern
and with an initializer represents a definition of the variable. You may not define a variable with external linkage twice.
From the C Standard (6.9.2 External object definitions)
1 If the declaration of an identifier for an object has file scope and an initializer, the declaration is an external definition for the identifier.
Pay attention to that in general it is not a good approach to use global variables.