Home > Enterprise >  Why I can't declare void * p in the end of longestCommonPrefix function?
Why I can't declare void * p in the end of longestCommonPrefix function?

Time:08-08

I was solving leetcode problems in c when compiler gave me strange error. Why I can't declare void * p in the end of longestCommonPrefix function?

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

char * longestCommonPrefix (char ** strs, int strsSize) {
    int bufsize = 16;
    int len = 0;
    char * ans = malloc(bufsize);

    char ch;
    while (true) {
        ch = (*strs)[len];
        for (int i = 1; i < strsSize; i  ) {
            if ((strs[i])[len] != ch || (strs[i])[len] == 0) goto _while_end;
        }
        if (len == bufsize) {
            bufsize  = 16;
            void * p = realloc (ans, bufsize);
            if (!p) return NULL;
            ans = p;
        }
        ans[len  ] = ch;
    }
_while_end:
    void * p = realloc (ans, len 1);
    if (!p) return 0;
    ans = p;
    ans[len] = 0;
    return ans;
}

int main () {
    char ** s = {"asdf", "asdw", "asdfe"};
    printf ("%s\n", longestCommonPrefix (s, 3));
    return 0;
}
main.c:27:2: error: expected expression
        void * p = realloc (ans, len 1);
        ^
main.c:28:7: error: use of undeclared identifier 'p'
        if (!p) return 0;
             ^
main.c:29:8: error: use of undeclared identifier 'p'
        ans = p;
              ^
main.c:35:15: warning: incompatible pointer types initializing 'char **' with an expression of type 'char [5]' [-Wincompatible-pointer-types]
        char ** s = {"asdf", "asdw", "asdfe"};
                     ^~~~~~
main.c:35:23: warning: excess elements in scalar initializer [-Wexcess-initializers]
        char ** s = {"asdf", "asdw", "asdfe"};
                             ^~~~~~
2 warnings and 3 errors generated.

CodePudding user response:

In C, only statements can be labeled, not declarations. Declarations and statements are two separate categories. (In C , declarations are included in statements, instead of separate, and can be labeled.) I do not believe there is a technical reason for this (such as some conflict in the formal grammar of the language); it is just a legacy of development of the C language.

An easy workaround is simply to use a null statement, ;, with the label:

_while_end:
    ;
    void * p = realloc (ans, len 1);

CodePudding user response:

Not sure why @mykola's answer is accepted, but the real reason is because goto labels can not precede declarations, they can only precede statements.

There are several solutions, one as outlined in the comment, but if you really want the declaration after a label you can force a statement after the label like this:

_while_end:; //<-- note semicolon
  void *p = realloc (ans, len 1);

CodePudding user response:

It depends on the standard used, the ANSI C does not allow intermingled declarations and code.

It is possible to do so since C99 standard.

Please configure your compiler to follow C99 standard to be able to build the code.

  • Related