3

I'm trying to write a recursive function (printPath) inside another function (dijkstraSSSP), but it gives me a compiler error.

When I run gcc dijkstra.c WGraph.c PQueue.c, it compiles just fine. However, when I run dcc -Wall -Werror -std=c11 -o dijkstra dijkstra.c WGraph.c PQueue.c. I got this error:

dijkstra.c:48:38: error: function definition is not allowed here
void printPath (int currentNode) {

Which I think it is because I define a function inside another function. If this is the case, how should I modify the code? Thanks a lot!

void dijkstraSSSP(Graph g, Vertex source) {
    int  dist[MAX_NODES];
    int  pred[MAX_NODES];
    bool vSet[MAX_NODES];  // vSet[v] = true <=> v has not been processed
    int s, t;

    PQueueInit();
    int nV = numOfVertices(g);
    for (s = 0; s < nV; s++) {
        joinPQueue(s);
        dist[s] = VERY_HIGH_VALUE;
        pred[s] = -1;
        vSet[s] = true;
    }

    dist[source] = 0;  

    int relaxWeight;
    for (s = 0; s < numOfVertices(g); s++) {
        s = leavePQueue(dist);
        //printf("iterating with s = %d\n", s);
        //printf("updating vSet[%d] = false\n", s);
        vSet[s] = false;
        for (t = 0; t < numOfVertices(g); t++) {
            //printf("iterating with t = %d\n", t);
            //printf("checking if s = %d is adj to t = %d and vSet[%d] = true\n", s, t, t);
            if (adjacent(g, s, t) != 0 && vSet[t] == true) {
                //printf("YES\n");
                relaxWeight = adjacent(g, s, t);
                if (dist[t] > dist[s] + relaxWeight) {
                    //printf("updating dist[%d] = dist[%d] + adjWeight[%d]\n", t, s, relaxWeight);
                    dist[t] = dist[s] + adjacent(g, s, t);
                    //printf("updating pred[%d] = %d\n", t, s);
                    pred[t] = s;
                }
            }
        }
    }
 
    void printPath (int currentNode) {
        if (pred[currentNode] == -1) {
            printf("%d", currentNode);
            return;
        } else {
            printPath (pred[currentNode]);
            printf("-%d", currentNode);
        }
    }

    for (int i = 0; i < numOfVertices(g); i++) {
        if (dist[i] == VERY_HIGH_VALUE) {
            printf("%d: no path\n", i);
        } else{
            printf("%d: distance = %d, shortest path: ", i, dist[i]);
            printPath(i);
            printf("\n");
        }
    }
}
4
  • 4
    Just move the function outside, to the global scope. Commented Mar 18, 2022 at 17:00
  • 1
    "inside another function" Why would you want to do this? Nested function definitions are not part of C standard. You would have to rely on compiler extensions. Commented Mar 18, 2022 at 17:03
  • Thanks for the reply. I'm very new to C and still learning. The reason I did this is because I would have to use the value in the pred[] array which was computed as part of the dijkstraSSSP function Commented Mar 18, 2022 at 17:08
  • "I think it is because I define a function inside another function." - you have rather answered your own question there haven't you? So define it outside. Commented Mar 18, 2022 at 20:30

2 Answers 2

4

Defining a function inside another function is not defined in the C Standard. gcc allows it as an extension, but most compilers don't.

You should move the definition of printPath outside the body of the dijkstraSSSP function, before it in the source code, and pass pred as an extra argument:

void printPath(const int *pred, int currentNode) {
    if (pred[currentNode] == -1) {
        printf("%d", currentNode);
    } else {
        printPath(pred, pred[currentNode]);
        printf("-%d", currentNode);
    }
}

void dijkstraSSSP(Graph g, Vertex source) {
    int  dist[MAX_NODES];
    int  pred[MAX_NODES];
    bool vSet[MAX_NODES];  // vSet[v] = true <=> v has not been processed
    int s, t;

    PQueueInit();
    int nV = numOfVertices(g);
    for (s = 0; s < nV; s++) {
        joinPQueue(s);
        dist[s] = VERY_HIGH_VALUE;
        pred[s] = -1;
        vSet[s] = true;
    }

    dist[source] = 0;  

    int relaxWeight;
    for (s = 0; s < numOfVertices(g); s++) {
        s = leavePQueue(dist);
        //printf("iterating with s = %d\n", s);
        //printf("updating vSet[%d] = false\n", s);
        vSet[s] = false;
        for (t = 0; t < numOfVertices(g); t++) {
            //printf("iterating with t = %d\n", t);
            //printf("checking if s = %d is adj to t = %d and vSet[%d] = true\n", s, t, t);
            if (adjacent(g, s, t) != 0 && vSet[t] == true) {
                //printf("YES\n");
                relaxWeight = adjacent(g, s, t);
                if (dist[t] > dist[s] + relaxWeight) {
                    //printf("updating dist[%d] = dist[%d] + adjWeight[%d]\n", t, s, relaxWeight);
                    dist[t] = dist[s] + adjacent(g, s, t);
                    //printf("updating pred[%d] = %d\n", t, s);
                    pred[t] = s;
                }
            }
        }
    }
 
    for (int i = 0; i < numOfVertices(g); i++) {
        if (dist[i] == VERY_HIGH_VALUE) {
            printf("%d: no path\n", i);
        } else{
            printf("%d: distance = %d, shortest path: ", i, dist[i]);
            printPath(pred, i);
            printf("\n");
        }
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

thanks a lot! this resolved the issue. However I have 1 error left which I'm not too sure what causes the problem. When I run dcc -Wall -Werror -std=c11 -o dijkstra dijkstra.c WGraph.c PQueue.c again. I have the following error: dijkstra.c:67:13: error: implicit declaration of function 'printPath' is invalid in C99 [-Werror,-Wimplicit-function-declaration] printPath(pred, i);
I just realised that this is because I placed the printPath function underneath the dijkstraSSSP :)
@dtrinh: yes, either put a declaration or the definition of printPath before the definition of dijkstraSSSP.
1

Move the definition of printPath outside of the body of dijkstraSSSP and, to give it access to pred, change it to accept two parameters instead of one. The additional parameter should have type int * and should point to the first element of pred.

In the call, pass pred for that new parameter. The array pred will be automatically converted to a pointer to its first element.

1 Comment

Thanks for the reply! yep, I changed the code to what you and chqrlie suggest and it worked.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.