0

Here is Define.c

 #include "Define.h"

// this line working

// Format date_format = { "YYMMDD", "%02u%02u%02u", 6, 3 };  // line1     

Format date_format;

// this line are now working

strcpy(date_format.format, "YYMMDD");            // line2
strcpy(date_format.scanformat, "%02u%02u%02u");  // line3
date_format.scansize = 3;                        // line4
date_format.printsize = 6;                       // line5

Here is Define.h

#ifndef _DEFINE_H
#define _DEFINE_H

typedef struct Format
{
    char format[256];
    char scanformat[256];
    unsigned int printsize;
    unsigned int scansize;

} Format;

extern Format date_format;

#endif

main.c

#include <stdio.h>
#include "Define.h"


int main(int argc, char* argv[])
{
    printf(date_format.format);
    getchar();
    return 0;
}

My question is why second definition in line no. 2/3/4/5 is not working? It is all I want with this struct initialization/definition/assignment. OR it must be contained within a method, but if so then why line1 is working correctly? I am using Visual Studio 2017

enter image description here

  • 5
    Code like `date_format.printsize = 5;` needs to be inside a function. – Retired Ninja May 03 '23 at 02:51
  • 1
    First expression is variable declaration with initialization, second one is assignment operation. – dimich May 03 '23 at 03:05
  • 1
    @Rakesh Solanki, Why not `Format date_format = { "YYMMDD", "%02u%02u%02u", 5, 3 };`? 5 instead of 6 – chux - Reinstate Monica May 03 '23 at 03:10
  • @chux actually it is 6 as in first line but I want to explain the problem, if I would have written `date_format.printsize = 6;` then also you might confuse why I repeated. – Rakesh Solanki May 03 '23 at 04:11
  • in your header you have `extern Format date_format` and in your Define.c file you have `Format date_format = { "YYMMDD", "%02u%02u%02u", 6, 3 }; ` One way would be to remove the latter, and have it initialised in your main.c file at program start. – jabroni May 03 '23 at 04:15
  • 1
    @RakeshSolanki Why do you want to do `date_format.printsize = 5; ` at all given `Format date_format = { "YYMMDD", "%02u%02u%02u", 6, 3 };`? Why change `.printsize`? – chux - Reinstate Monica May 03 '23 at 04:15
  • @jabroni Even in Main.c it is giving the same error as "Expected ;" for the line `date_format.printsize = 5;` with or without the first line, very strange. This means it only allows intialization and not any assignment outside of any method. – Rakesh Solanki May 03 '23 at 05:22
  • If you comment those lines out what happens? Does it compile? I am wondering if you have a syntax error missing elsewhere in your code (hence the `Expected ';'`). Also, you have declared your struct as `typedef struct Format {...} Format` when I think you need to have `typedef struct {...} Format;` instead. You haven't provided much context into your `.c` file either. It's a little hard to debug the way you have written your question. It is best to provide an example in the format of a C program. – jabroni May 03 '23 at 05:30
  • @jabroni Please check I have updated full code with screenshot, and this project have only these 3 files here, and I confirm that with only line1 the code works perfect. – Rakesh Solanki May 03 '23 at 10:01
  • @Retired Ninja Why? `Format date_format = { "YYMMDD", "%02u%02u%02u", 6, 3 }; // line1` this works even outside any method while `Format date_format; // this line are now working strcpy(date_format.format, "YYMMDD"); // line2 strcpy(date_format.scanformat, "%02u%02u%02u"); // line3 date_format.scansize = 3; // line4 date_format.printsize = 5; // line5` is not working. I can't understand any difference betwen the two and what I want to perform, I think they are just different style of assignment statements(if I am not wrong!) – Rakesh Solanki May 03 '23 at 10:06
  • 1
    @RakeshSolanki The initialization can be calculated at compile time and any code necessary for it is executed before `main`. The assignment statement is purely runtime code. [Why is it that I can't assign values to member variable of structures outside functions?](https://stackoverflow.com/questions/62509360/why-is-it-that-i-cant-assign-values-to-member-variable-of-structures-outside-fu) and the rabbit hole of linked questions may help. Short answer is it's just how the language works. – Retired Ninja May 03 '23 at 11:39
  • @Retired Ninja So `Format date_format = { "YYMMDD", "%02u%02u%02u", 6, 3 };` vs `Format date_format; strcpy(date_format.format, "YYMMDD"); strcpy(date_format.scanformat, "%02u%02u%02u"); date_format.scansize = 3; date_format.printsize = 5; ` is not just a different style but also that former is strictly initialization(can be used outside of method) while the latter is assignment. (and can only be used inside any method). This is what you mean to say? – Rakesh Solanki May 03 '23 at 12:29
  • 1
    Yes, initialization is special. – Retired Ninja May 03 '23 at 12:31
  • @Retired Ninja But again for other variables which are not struct like int/char/char* would it make any difference because there we have not different syntax for intialization and assignment? – Rakesh Solanki May 03 '23 at 12:31
  • [Why should I not upload images of code/data/errors?](https://meta.stackoverflow.com/questions/285551/why-should-i-not-upload-images-of-code-data-errors) – n. m. could be an AI May 03 '23 at 15:45

2 Answers2

1

I think what you are asking is why can't you initialise global struct variables and then extern them - the answer to this is because the compiler has no idea what you want. You're declaring global date_format variables with no initialisation in a file outside of main.

You can move your attempt at initialisation from Define.c to be declared at a global level of main.c. But you don't want this. Another method is via static initialisation (which you have already tried). I'm also a little confused why you don't want to put the initalisation int a function? But anyway...

What I assume you want is to initialise the struct in another file, and have those same values used across to another part of the program. Your problem then lies with how you have declared your extern and re-declaration of Format date_format.

You want to init the struct vars in Define.c:

#include "define.h"

Format date_format;

void initStuff()
{
    strcpy(date_format.format, "YYMMDD");            // line2
    strcpy(date_format.scanformat, "%02u%02u%02u");  // line3
    date_format.scansize = 3;                        // line4
    date_format.printsize = 6;                       // line5
}

Then in Define.h tell the compiler that the struct is an extern:

#ifndef _DEFINE_H
#define _DEFINE_H

#include <string.h>

typedef struct Format
{
    char format[256];
    char scanformat[256];
    unsigned int printsize;
    unsigned int scansize;

} Format;

extern Format date_format;

void initStuff();

#endif

Then in main call date_format directly:

int main()
{
    initStuff();
    printf("%s\n", date_format.format);
    printf("%s\n", date_format.scanformat);
    printf("%i\n", date_format.scansize);
    printf("%i\n", date_format.printsize);

    return 0;
}

Output:

YYMMDD
%02u%02u%02u
3
6
jabroni
  • 167
  • 16
0

You are trying to execute function calls outside of a function try moving the code from Define.c to main or put them inside an init function like this:

#include "Define.h"     

Format date_format;

void date_format_init(void)
{
    strcpy(date_format.format, "YYMMDD");
    strcpy(date_format.scanformat, "%02u%02u%02u");
    date_format.scansize = 3;
    date_format.printsize = 5;
}

And inside main() call the function

#include <stdio.h>
#include "Define.h"

int main(int argc, char* argv[])
{
    date_format_init();
    printf(date_format.format);
    getchar();
    return 0;
}

And in Define.h add void date_format_init(void);

user16217248
  • 3,119
  • 19
  • 19
  • 37
  • I have not used any method, I just want to initialize values to global variable and I don't think any method is compulsory to initialize. Even the `Format date_format = { "YYMMDD", "%02u%02u%02u", 6, 3 };` is working correctly without any sort of method. But why not other method mentioned in question is working for initialization? – Rakesh Solanki May 03 '23 at 15:38
  • Even if I am not using the `strcpy()` then also the other style of initialization is not working. – Rakesh Solanki May 03 '23 at 15:45