5 Replies - 342 Views - Last Post: 06 June 2019 - 01:22 PM Rate Topic: -----

#1 ArtificialSoldier   User is offline

  • D.I.C Lover
  • member icon

Reputation: 2334
  • View blog
  • Posts: 7,113
  • Joined: 15-January 14

Static / non-static declaration

Posted 05 June 2019 - 05:13 PM

GCC is warning me about declaring a function statically:

Quote

static declaration of âis_logged_inâ follows non-static declaration


The code doesn't have any function prototypes in it, but from what I hear it will implicitly declare functions if they aren't explicitly prototyped. But I'm confused because the file I pulled this function out of to test also defines almost every function statically and also does not prototype anything.

So, GCC likes this:

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

const char *TEST_DATA_1 = "";
const char *TEST_DATA_2 = "";

int main (void) {

}

int is_logged_in(const char *session_data) {

}


But not this:

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

const char *TEST_DATA_1 = "";
const char *TEST_DATA_2 = "";

int main (void) {

}

static int is_logged_in(const char *session_data) {

}


This is pulled out of code that's used to build an RPM using OSC, so maybe there's some magic going on behind the scenes with the spec file or something else to define function prototypes first? Otherwise I'm not sure why it's complaining.

Is This A Good Question/Topic? 0
  • +

Replies To: Static / non-static declaration

#2 jimblumberg   User is offline

  • member icon

Reputation: 5733
  • View blog
  • Posts: 17,568
  • Joined: 25-December 09

Re: Static / non-static declaration

Posted 05 June 2019 - 05:40 PM

Quote

The code doesn't have any function prototypes in it, but from what I hear it will implicitly declare functions if they aren't explicitly prototyped.

That depends on what version of the standard you are using when compiling your code. Modern C no longer allows implicit function parameters, return values or functions definitions after their use.

Quote

So, GCC likes this:

Not really:

Quote

||=== Build: Debug in chomework (compiler: GCC 8-1) ===|
main.c|14|warning: no previous declaration for ‘is_logged_in’ [-Wmissing-declarations]|
main.c||In function ‘is_logged_in’:|
main.c|14|warning: unused parameter ‘session_data’ [-Wunused-parameter]|
main.c|16|warning: control reaches end of non-void function [-Wreturn-type]|
||=== Build finished: 0 error(s), 3 warning(s) (0 minute(s), 0 second(s)) ===|


By the way, don't forget that implicit return values, and function parameters default to type int

Quote

Otherwise I'm not sure why it's complaining.

Well one of the things the compiler will complain about is that you're not using that static function. And the difference is probably because of the differences of linkage. Remember a static function is only usable in the function it is defined.

By the way this is what my compiler says about the second snippet:

Quote

||=== Build: Debug in chomework (compiler: GCC 8-1) ===|
main.c||In function ‘is_logged_in’:|
main.c|16|warning: no return statement in function returning non-void [-Wreturn-type]|
main.c|14|warning: unused parameter ‘session_data’ [-Wunused-parameter]|
main.c|14|warning: ‘is_logged_in’ defined but not used [-Wunused-function]|
||=== Build finished: 0 error(s), 3 warning(s) (0 minute(s), 0 second(s)) ===|


Notice, if you ignore the unused parameter and return value warnings, it only warns about the unused function, not the no previous declaration warning.


Jim

This post has been edited by jimblumberg: 05 June 2019 - 05:41 PM

Was This Post Helpful? 0
  • +
  • -

#3 ArtificialSoldier   User is offline

  • D.I.C Lover
  • member icon

Reputation: 2334
  • View blog
  • Posts: 7,113
  • Joined: 15-January 14

Re: Static / non-static declaration

Posted 05 June 2019 - 05:47 PM

Right, I shouldn't have removed so much code, the function does get called from main and both of them always return an int. The version that does use static functions to build the RPM is fairly verbose.

It does look like the server is a bit behind:

Quote

[[email protected] c]# gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)

Was This Post Helpful? 0
  • +
  • -

#4 jimblumberg   User is offline

  • member icon

Reputation: 5733
  • View blog
  • Posts: 17,568
  • Joined: 25-December 09

Re: Static / non-static declaration

Posted 05 June 2019 - 06:03 PM

Quote

the function does get called from main and both of them always return an int.

And what about the parameter, it will default to an int as well?

It is really better to always prototype your functions, and really the prototype should also have named parameters. The prototype really helps document the code if used properly and using implicit values is frowned upon for modern code.

Jim
Was This Post Helpful? 0
  • +
  • -

#5 ArtificialSoldier   User is offline

  • D.I.C Lover
  • member icon

Reputation: 2334
  • View blog
  • Posts: 7,113
  • Joined: 15-January 14

Re: Static / non-static declaration

Posted 06 June 2019 - 12:52 PM

Which parameter, the session_data parameter? That's not an int. This is a version should run, I removed most of the code of the second function and most of the tests and test data, but you get the idea:

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

const char *TEST_DATA_5 = "s:1:\"1\";}userid|i:6546585676518646548654156486454644654324435457859651687432198786465748964646846646646546865534654334354354;userdata";

int main (void) {
  
  if (is_logged_in(TEST_DATA_5) == 1) {
    printf("Found ID in data 5\n");
  }
  else {
    printf("No ID found in data 5\n");
  }

  return 0;
}

int is_logged_in(const char *session_data) {
  if (!session_data) {
    return 0;
  }

  /* Check for identity */
  const char *IDENTITY = "{s:8:\"identity\";s:";
  const char *char_pos = strstr(session_data, IDENTITY);
  if (char_pos) {
    /* Found identity, read value between quotes */
    char_pos += 18; //strlen(IDENTITY);
    while (*char_pos && *char_pos != '"') {
      char_pos++;
    }
    if (*char_pos) {
      const char *char_pos2 = char_pos + 1;
      while (*char_pos2 && *char_pos2 != '"') {
        char_pos2++;
      }

      /* Check for non-empty value */
      if (*char_pos2 && (char_pos2 > char_pos + 1)) {
        printf("Found identity\n");
        return 1;
      }
    }
  }

  return 0;
}


I don't get warnings when I compile, although that may be due to compiler settings. I do remember the discussion of prototyping from school, so I wasn't sure what was going on here or if things had changed since then, or if there was something special going on with the OSC build process to make the RPM. The original source with everything defined as static that I pulled this out of to test doesn't even have a main function, so obviously it fits in somehow else that I haven't fully looked into.
Was This Post Helpful? 0
  • +
  • -

#6 jimblumberg   User is offline

  • member icon

Reputation: 5733
  • View blog
  • Posts: 17,568
  • Joined: 25-December 09

Re: Static / non-static declaration

Posted 06 June 2019 - 01:22 PM

Quote

Which parameter, the session_data parameter? That's not an int.

Well since you're using an implicit declaration it will be treated as an int by the compiler. This is why using implicit values is no longer supported in the current standards, too many chances for hard to trace errors.

Quote

I don't get warnings when I compile, although that may be due to compiler settings.

Yes, by default most compilers are very lax at reporting anything other than mandatory warnings and errors. IMO, compiling without enabling at least -Wall -Wextra -pedantic -pedantic-errors is asking for trouble.

Jim
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1