2

Protocol.h

typedef struct sDevice_d
{
    char name[24];
    signed int (*Send)(unsigned char*, unsigned short);
    signed int (*Recv)(unsigned char*, unsigned short);
} sDevice_d, *psDevice_d;

Device.c

#include "Protocol.h"

sDevice_d sDevice = { "ten", I2c_Send };
psDevice_d psDevice = &sDevice;

static signed int I2c_Send(unsigned char* buf, unsigned short len)
{
    return 0;
}

In the code above I am getting the following Error:

error C2099: initializer is not a constant

Please help me in resolving this.

I am using Visual studio Win32 application.

SHRI
  • 2,406
  • 6
  • 32
  • 48
  • Is I2c_Send prototype available before structure initialization? – Alex F Sep 11 '13 at 14:01
  • 1
    @NemanjaBoric You sure? The struct typedef is incomplete. – James M Sep 11 '13 at 14:02
  • @JamesMcLaughlin Oh, yeah, sorry about that, I've compiled with g++. – Nemanja Boric Sep 11 '13 at 14:05
  • @AlexFarber I2c_Send is available in the order I have shown in code. Initialization is global to Device.c – SHRI Sep 11 '13 at 14:09
  • 1
    You need to add a prototype for `I2c_Send` prior to the initialization of `sDevice`. – Carey Gregory Sep 11 '13 at 14:11
  • possible duplicate of [compile error C2099: initializer is not a constant](http://stackoverflow.com/questions/6131455/compile-error-c2099-initializer-is-not-a-constant) – alk Sep 11 '13 at 14:14
  • @Carey Gregory how can I add that? – SHRI Sep 11 '13 at 14:15
  • An even better dupe is here: http://stackoverflow.com/q/3025050/694576 – alk Sep 11 '13 at 14:17
  • Static initialisation is not possible in C the way you try this. See the answers to the questions linked as dupes for explanations. – alk Sep 11 '13 at 14:19
  • Function prototypes are a fundamental element of C. Go learn about them before proceeding further. – Carey Gregory Sep 11 '13 at 14:25
  • @SHRI: Your code compiles perfectly fine in VS compiler, assuming the function is declared in advance (otherwise it would produce a different error). Apparently the code you posted does not illustrate the real reason for the error. – AnT stands with Russia Sep 11 '13 at 16:39
  • 2
    None of the alleged "dupes" posted so far have any relevance to this question. The code posted above is correct and all initializers are actually constants (address constants, specifically). It does not really produce "initializer is not constant" error in VS. Apparently, the code is inaccurate and/or irrelevant. – AnT stands with Russia Sep 11 '13 at 16:42
  • @alk: What exactly do you see as "not possible" here? – AnT stands with Russia Sep 11 '13 at 16:43
  • It would have been good to add the line on which the error is. – qdii Sep 11 '13 at 17:14
  • @AndreyT Thanks for the comments. Error is solved when I added prototype of static function. – SHRI Sep 12 '13 at 13:26
  • 1
    @SHRI - Just to be clear, prototypes are recommended, but not strictly required. But visibility to a function definition ***is*** required before it is used anywhere. For example, in your code, if the function itself was removed from the .c, and placed into the .h, (replacing the prototype), it would compile and build. So in your case, visibility was the limiting issue. In most compilers, there are settings that allow you to omit prototypes. Not recommended however. Look ***[here](http://stackoverflow.com/questions/4914589/c-prototype-functions)*** for a good discussion on prototypes. – ryyker Sep 12 '13 at 14:23

1 Answers1

4

The function I2c_Send needs to be defined and visible before attempting to create and initializing a struct using it in its initializer list. I have included an adaptation of your code below that illustrates this in two files:

protocol.h

typedef struct
{
    char name[24];
    signed int (*Send)(unsigned char*, unsigned short);
    signed int (*Recv)(unsigned char*, unsigned short);
} S_DEVICE;

//prototype here
static signed int I2c_Send(unsigned char* buf, unsigned short len); 

device.c

#include "protcol.h"

S_DEVICE sDevice_d = {"ten", I2c_Send, I2c_Send}; 

int main(void)
{
   return 0;
}

//define here
static signed int I2c_Send(unsigned char* buf, unsigned short len)
{
    return 0;
}

This source compiled and built using an ANCI C compiler (using C99 extensions) and should yield similar results in your Visual Studios, Win32 environment.

ryyker
  • 22,849
  • 3
  • 43
  • 87
  • Note that the user's example includes `"Protocol.h"` before attempting to declare `sDevice_d`, so `I2c_Send()` is probably declared in there, and shouldn't need redeclaration. Additionally, this version of your answer doesn't even address the actual question. (Why did you need to make a new answer? The system _should_ allow you to completely rewrite your original answer as needed, as far as I can tell.) – This isn't my real name Sep 11 '13 at 16:33
  • @ElchononEdelson - Agreed, I did that here for completeness, so I could prove the build before posting. I alluded to that in the text before the code as well. As for answering the original question "error C2099: initializer is not a constant", I think the new answer does address it. The structs were not initialized correctly and the function needed to be declared and visible before being used. – ryyker Sep 11 '13 at 16:36
  • Things are a big clearer now. I suggest that you rewrite your answers (both of them) as one large answer, using a text editor such as notepad, then delete one of these answers and completely replace the text of the other answer with your updated corrected version. – This isn't my real name Sep 11 '13 at 16:40
  • @ElchononEdelson - Done. Thanks for the suggestion and your attention to detail. – ryyker Sep 11 '13 at 17:11
  • 1
    Still wrong, just differently. You _can_ create an alias that has the same name as a struct. The code `struct foo {...}` declares a new type named `struct foo`, for which variables must be declared as `struct foo var_a`, the code `typedef struct foo {...} foo` declares a new type named `struct foo`, and _at the same time_ creates an alias named `foo`, and you can then declare variables as `foo var_b`. – This isn't my real name Sep 11 '13 at 17:31
  • Also, see the comments from "AndreyT" on the question. – This isn't my real name Sep 11 '13 at 17:37
  • @ElchononEdelson - regarding AndreyT's comments, I have been caught chasing a red herring. Thanks though for the clarifications on what constitutes a struct alias and type. +1. – ryyker Sep 12 '13 at 14:05