Definition of structures and arrays - c

I have the following code:
struct dmparam {
char *p;
char *v;
};
struct dmobj {
int a;
int b;
struct dmparam *dmparam;
};
struct dmarray {
struct dmobj *dmobj;
struct dmentry {
int func;
struct dmarray *dmarray;
} *dmentry;
};
struct dmarray atest = {
{//objs
{1, 11, NULL},
{2, 22,
{//params
{"p1", "v1"},
{"p2", "v2"},
}//params
}
},//objs
{//arays
{101, {
{//objs
{1, 11, NULL},
{2, 22,
{//params
{"p1", "v1"},
{"p2", "v2"},
}//params
}
},//objs
NULL
}
}
}//arrays
};
This code generate the following compilation warnings:
test.c:26:2: warning: braces around scalar initializer [enabled by default]
{//objs
^
test.c:26:2: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:27:2: warning: braces around scalar initializer [enabled by default]
{1, 11, NULL},
^
test.c:27:2: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:27:2: warning: initialization makes pointer from integer without a cast [enabled by default]
test.c:27:2: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:27:2: warning: excess elements in scalar initializer [enabled by default]
test.c:27:2: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:27:2: warning: excess elements in scalar initializer [enabled by default]
test.c:27:2: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:28:2: warning: braces around scalar initializer [enabled by default]
{2, 22,
^
test.c:28:2: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:28:2: warning: initialization makes pointer from integer without a cast [enabled by default]
test.c:28:2: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:28:2: warning: excess elements in scalar initializer [enabled by default]
test.c:28:2: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:29:3: warning: braces around scalar initializer [enabled by default]
{//params
^
test.c:29:3: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:30:3: warning: braces around scalar initializer [enabled by default]
{"p1", "v1"},
^
test.c:30:3: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:30:3: warning: initialization from incompatible pointer type [enabled by default]
test.c:30:3: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:30:3: warning: excess elements in scalar initializer [enabled by default]
test.c:30:3: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:31:3: warning: braces around scalar initializer [enabled by default]
{"p2", "v2"},
^
test.c:31:3: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:31:3: warning: initialization from incompatible pointer type [enabled by default]
test.c:31:3: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:31:3: warning: excess elements in scalar initializer [enabled by default]
test.c:31:3: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:31:3: warning: excess elements in scalar initializer [enabled by default]
test.c:31:3: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:32:3: warning: excess elements in scalar initializer [enabled by default]
}//params
^
test.c:32:3: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:33:2: warning: excess elements in scalar initializer [enabled by default]
}
^
test.c:33:2: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:35:2: warning: braces around scalar initializer [enabled by default]
{//arays
^
test.c:35:2: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:36:3: warning: braces around scalar initializer [enabled by default]
{101, {
^
test.c:36:3: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:36:3: warning: initialization makes pointer from integer without a cast [enabled by default]
test.c:36:3: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:36:3: warning: braces around scalar initializer [enabled by default]
test.c:36:3: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:37:5: warning: braces around scalar initializer [enabled by default]
{//objs
^
test.c:37:5: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:38:5: warning: braces around scalar initializer [enabled by default]
{1, 11, NULL},
^
test.c:38:5: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:38:5: warning: initialization makes pointer from integer without a cast [enabled by default]
test.c:38:5: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:38:5: warning: excess elements in scalar initializer [enabled by default]
test.c:38:5: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:38:5: warning: excess elements in scalar initializer [enabled by default]
test.c:38:5: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:39:5: warning: braces around scalar initializer [enabled by default]
{2, 22,
^
test.c:39:5: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:39:5: warning: initialization makes pointer from integer without a cast [enabled by default]
test.c:39:5: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:39:5: warning: excess elements in scalar initializer [enabled by default]
test.c:39:5: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:40:6: warning: braces around scalar initializer [enabled by default]
{//params
^
test.c:40:6: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:41:6: warning: braces around scalar initializer [enabled by default]
{"p1", "v1"},
^
test.c:41:6: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:41:6: warning: initialization from incompatible pointer type [enabled by default]
test.c:41:6: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:41:6: warning: excess elements in scalar initializer [enabled by default]
test.c:41:6: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:42:6: warning: braces around scalar initializer [enabled by default]
{"p2", "v2"},
^
test.c:42:6: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:42:6: warning: initialization from incompatible pointer type [enabled by default]
test.c:42:6: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:42:6: warning: excess elements in scalar initializer [enabled by default]
test.c:42:6: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:42:6: warning: excess elements in scalar initializer [enabled by default]
test.c:42:6: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:43:6: warning: excess elements in scalar initializer [enabled by default]
}//params
^
test.c:43:6: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:44:5: warning: excess elements in scalar initializer [enabled by default]
}
^
test.c:44:5: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:47:3: warning: excess elements in scalar initializer [enabled by default]
}
^
test.c:47:3: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:47:3: warning: excess elements in scalar initializer [enabled by default]
test.c:47:3: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
What I m doing wrong?
What's the best way to write this?

This code compiles as a complete source file:
struct dmparam {
char *p;
char *v;
};
struct dmobj {
int a;
int b;
struct dmparam *dmparam;
};
struct dmarray {
struct dmobj *dmobj;
struct dmentry {
int func;
struct dmarray *dmarray;
} *dmentry;
};
struct dmparam dp1 = { "abc", "xyz" };
struct dmparam dp2 = { "Mercury", "Uranus" };
struct dmobj do1 = { 1, 1, &dp1 };
struct dmobj do2 = { 2, -987, &dp2 };
struct dmentry de1 = { 0, 0 };
struct dmarray da1 = { &do1, &de1 };
Observe that you effectively have:
struct dmentry {
int func;
struct dmarray *dmarray;
};
struct dmarray {
struct dmobj *dmobj;
struct dmentry *dmentry;
};
So there are only two items in each struct dmarray, both pointers. Also, the struct dmentry is not restricted in scope; the rules in C++ are different.
All that is standard C90 code (as well as C99 and C11). In C99 or later, you can also do the initialization like this:
struct dmarray da2 =
{
.dmobj = &(struct dmobj){ 9, 99, &(struct dmparam){ "Frigid", "Roasting" } },
.dmentry = &(struct dmentry){ 1, &(struct dmarray){ 0, 0 } }
};
Note that you end up with needing a pointer to a struct dmarray while you're initializing another one. I ducked and use a null pointer in the nested structure, but you could go deeper if you wanted to.
Just for the record, the code was tested on Mac OS X 10.10.5 using 'gcc' (actually clang) from XCode 6.4:
$ gcc -std=c99 -pedantic -O3 -g -Wall -Wextra -Werror -c so.32014285.c
$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.5.0
Thread model: posix
$
There's an outside chance that despite requesting pedantic adherence to the C99 standard, GCC is letting an extension through.

Related

Initializing struct array with arrays as elements of the struct

I am trying to initialize an array of structs that contain an array. Looking at
this and
this,
I think a pretty reasonable attempt is this:
struct Score_t{
int * dice;
int numDice;
int value;
};
struct Score_t Scores[NUMSCORES] = {
[0]={{0,0,0},3,1000},
[1]={{1,1,1},3,200},
[2]={{2,2,2},3,300},
[3]={{3,3,3},3,400},
[4]={{4,4,4},3,500},
[5]={{5,5,5},3,600},
[6]={{0},3,100},
[7]={{4},3,50}
};
However I can't get this to compile. Do you have any ways to get this done?
Edit: Forgot the error message: (snipped)
[5]={{5,5,5},3,600},
^
greed.c:79:2: warning: (near initialization for ‘Scores[5].dice’) [enabled by default]
greed.c:79:2: warning: initialization makes pointer from integer without a cast [enabled by default]
greed.c:79:2: warning: (near initialization for ‘Scores[5].dice’) [enabled by default]
greed.c:79:2: warning: excess elements in scalar initializer [enabled by default]
greed.c:79:2: warning: (near initialization for ‘Scores[5].dice’) [enabled by default]
greed.c:79:2: warning: excess elements in scalar initializer [enabled by default]
greed.c:79:2: warning: (near initialization for ‘Scores[5].dice’) [enabled by default]
greed.c:80:2: warning: braces around scalar initializer [enabled by default]
int * can't be initialized with { } (not match)
So change to like this.
struct Score_t Scores[NUMSCORES] = {
[0]={(int[]){0,0,0},3,1000},
[1]={(int[]){1,1,1},3,200},
[2]={(int[]){2,2,2},3,300},
[3]={(int[]){3,3,3},3,400},
[4]={(int[]){4,4,4},3,500},
[5]={(int[]){5,5,5},3,600},
[6]={(int[]){0},3,100}, //It doesn't know the number of elements
[7]={(int[]){4},3,50} //change to [7]={(int[3]){4},3,50} or [7]={(int[]){4},1,50}
};

Intercommunication between Python MPI master and C MPI worker?

I'm trying to write an MPI worker in C that will communicate with the MPI master, written in python. The master will send out scatters and gathers, and the C worker should receive those and return variables via gather. The problem is, I'm having trouble successfully writing the worker file.
(The reason the worker is in C is because this code is a skeleton to wrap around preexisting python and C programs.)
Here is the code I've written:
#include <stdio.h>
#include <mpi.h>
MPI_Comm comm;
MPI_Comm_get_parent(&comm);
int myid, world_size, size;
int root = 0;
int* endloop = malloc(sizeof(int));
int nelements1 = 1E3;
int nelements2 = 1E6;
float* input = malloc(sizeof(float) * nelements1);
float output[nelements2];
int randomarray(){
float array[nelements2];
srand(time(NULL));
for( i = 0; i < nelements2; i++ ){
array[i] = rand() % 0 + 1E6;
}
return array;
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
MPI_Comm_remote_size(comm, &size);
output = randomarray();
MPI_Scatter(endloop, 1, MPI_INT, root, comm);
while ( endloop[0] < 1) {
MPI_Barrier(comm);
MPI_Scatter(input, nelements1, MPI_FLOAT, root, comm);
MPI_Barrier(comm);
MPI_Gather(output, nelements2, MPI_FLOAT, root, comm);
MPI_Scatter(endloop, 1, MPI_INT, root, comm);
}
MPI_Finalize();
And the error output when I attempt to compile is:
maddie#exo:~/code/bart_commloop$ mpicc worker.c -o worker
worker.c:5:21: error: expected declaration specifiers or ‘...’ before ‘&’ token
worker.c:9:16: warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]
worker.c:9:1: error: initializer element is not constant
worker.c:12:1: error: initializer element is not constant
worker.c:13:7: error: variably modified ‘output’ at file scope
worker.c: In function ‘randomarray’:
worker.c:18:7: error: ‘i’ undeclared (first use in this function)
worker.c:18:7: note: each undeclared identifier is reported only once for each function it appears in
worker.c:19:21: warning: division by zero [-Wdiv-by-zero]
worker.c:22:2: warning: return makes integer from pointer without a cast [enabled by default]
worker.c:22:2: warning: function returns address of local variable [enabled by default]
worker.c:28:8: error: incompatible types when assigning to type ‘float[1]’ from type ‘int’
worker.c:30:1: warning: passing argument 4 of ‘MPI_Scatter’ makes pointer from integer without a cast [enabled by default]
/usr/lib/openmpi/include/mpi.h:1197:20: note: expected ‘void *’ but argument is of type ‘int’
worker.c:30:1: warning: passing argument 5 of ‘MPI_Scatter’ makes integer from pointer without a cast [enabled by default]
/usr/lib/openmpi/include/mpi.h:1197:20: note: expected ‘int’ but argument is of type ‘MPI_Comm’
worker.c:30:1: error: too few arguments to function ‘MPI_Scatter’
/usr/lib/openmpi/include/mpi.h:1197:20: note: declared here
worker.c:34:2: warning: passing argument 4 of ‘MPI_Scatter’ makes pointer from integer without a cast [enabled by default]
/usr/lib/openmpi/include/mpi.h:1197:20: note: expected ‘void *’ but argument is of type ‘int’
worker.c:34:2: warning: passing argument 5 of ‘MPI_Scatter’ makes integer from pointer without a cast [enabled by default]
/usr/lib/openmpi/include/mpi.h:1197:20: note: expected ‘int’ but argument is of type ‘MPI_Comm’
worker.c:34:2: error: too few arguments to function ‘MPI_Scatter’
/usr/lib/openmpi/include/mpi.h:1197:20: note: declared here
worker.c:36:2: warning: passing argument 4 of ‘MPI_Gather’ makes pointer from integer without a cast [enabled by default]
/usr/lib/openmpi/include/mpi.h:1058:20: note: expected ‘void *’ but argument is of type ‘int’
worker.c:36:2: warning: passing argument 5 of ‘MPI_Gather’ makes integer from pointer without a cast [enabled by default]
/usr/lib/openmpi/include/mpi.h:1058:20: note: expected ‘int’ but argument is of type ‘MPI_Comm’
worker.c:36:2: error: too few arguments to function ‘MPI_Gather’
/usr/lib/openmpi/include/mpi.h:1058:20: note: declared here
worker.c:37:2: warning: passing argument 4 of ‘MPI_Scatter’ makes pointer from integer without a cast [enabled by default]
/usr/lib/openmpi/include/mpi.h:1197:20: note: expected ‘void *’ but argument is of type ‘int’
worker.c:37:2: warning: passing argument 5 of ‘MPI_Scatter’ makes integer from pointer without a cast [enabled by default]
/usr/lib/openmpi/include/mpi.h:1197:20: note: expected ‘int’ but argument is of type ‘MPI_Comm’
worker.c:37:2: error: too few arguments to function ‘MPI_Scatter’
/usr/lib/openmpi/include/mpi.h:1197:20: note: declared here
worker.c:40:1: error: expected declaration or statement at end of input
The issue seems to be the formatting of my MPI calls, but I'm not sure what to fix there.
Any help would be greatly appreciated. Thank you!

error: warning: incompatible implicit declaration of built-in function ‘memcpy’ [enabled by default]

I get this error.
error: warning: incompatible implicit declaration of built-in function ‘memcpy’ [enabled by default]
This is the code:
int arr[ 12] = {1,0,0,0,0,0,0,0,0,0,9370, 0};
void *a = &arr;
memcpy(machine->mem, a,12*4);
What I am doing wrong?
You likely forgot to include <string.h>.
Add #include <string.h> to the top of your file.

parameter ‘my 2D-arr’ is initialized

Consider this code:
enum
{
ERR_START,
ERR_CANNOTOPENFILE,
ERR_CANNOTCONNECT,
ERR_CANNOTCONNECTWITH,
ERR_CANNOTGETHOSTNAME,
ERR_CANNOTSEND,
};
char* ERR_MESSAGE[] =
{
[ERR_START] = "Nothing",
[ERR_CANNOTOPENFILE] = "Cannot open '%s' filename.\n",
[ERR_CANNOTCONNECT] = "Cannot connect.\n",
[ERR_CANNOTCONNECTWITH] = "Cannot connect with '%s'.\n",
[ERR_CANNOTGETHOSTNAME] = "Cannot get host name.\n",
[ERR_CANNOTSEND] = "Cannot send.\n",
};
Given this erros:
error.h:27:1: error: parameter ‘ERR_MESSAGE’ is initialized
error.h:29:2: error: array index in non-array initializer
error.h:29:2: error: (near initialization for ‘ERR_MESSAGE’)
error.h:29:2: warning: initialization from incompatible pointer type
error.h:30:2: error: array index in non-array initializer
[....]
I'm compiling with -std=c99.
How to fix this?
I think you are getting this message because another syntax error in the file (or something included before it). I pasted the code into a standalone C file and got no compile errors with gcc -std=c99 -c test.c and my GCC version is gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2).
A likely error (maybe the only one) is if there's a function declaration that is missing a semicolon. With the code
enum
{
ERR_START,
ERR_CANNOTOPENFILE,
ERR_CANNOTCONNECT,
ERR_CANNOTCONNECTWITH,
ERR_CANNOTGETHOSTNAME,
ERR_CANNOTSEND,
};
void foo()
char* ERR_MESSAGE[] =
{
[ERR_START] = "Nothing",
[ERR_CANNOTOPENFILE] = "Cannot open '%s' filename.\n",
[ERR_CANNOTCONNECT] = "Cannot connect.\n",
[ERR_CANNOTCONNECTWITH] = "Cannot connect with '%s'.\n",
[ERR_CANNOTGETHOSTNAME] = "Cannot get host name.\n",
[ERR_CANNOTSEND] = "Cannot send.\n",
};
I get the similar errors
est.c: In function ‘foo’:
test.c:13:1: error: parameter ‘ERR_MESSAGE’ is initialized
test.c:15:5: error: array index in non-array initializer
test.c:15:5: error: (near initialization for ‘ERR_MESSAGE’)
test.c:15:5: warning: initialization from incompatible pointer type [enabled by default]
test.c:15:5: warning: (near initialization for ‘ERR_MESSAGE’) [enabled by default]
test.c:16:5: error: array index in non-array initializer
test.c:16:5: error: (near initialization for ‘ERR_MESSAGE’)
test.c:16:5: warning: excess elements in scalar initializer [enabled by default]
test.c:16:5: warning: (near initialization for ‘ERR_MESSAGE’) [enabled by default]
[...]

How to initialize a unsigned char array?

What I am really trying to achieve is an array of dynamic byte patterns that I can use as a pattern searcher when I buffer binary files. But I am starting off basic for now. I have the following code that I based off of an example found on StackOverflow.
How to Initialize a Multidimensional Char Array in C?
typedef unsigned char BYTE;
int main()
{
BYTE *p[2][4] = {
{0x44,0x58,0x54,0x31},
{0x44,0x58,0x54,0x00}
};
return 0;
}
I compile it with mingw32 for Windows.
D:\> gcc example.c -o example.exe
I get the following warnings when I try to compile.
example.c: In function 'main':
example.c:6:3: warning: initialization makes pointer from integer without a cast [enabled by default]
example.c:6:3: warning: (near initialization for 'p[0][0]') [enabled by default]
example.c:6:3: warning: initialization makes pointer from integer without a cast [enabled by default]
example.c:6:3: warning: (near initialization for 'p[0][1]') [enabled by default]
example.c:6:3: warning: initialization makes pointer from integer without a cast [enabled by default]
example.c:6:3: warning: (near initialization for 'p[0][2]') [enabled by default]
example.c:6:3: warning: initialization makes pointer from integer without a cast [enabled by default]
example.c:6:3: warning: (near initialization for 'p[0][3]') [enabled by default]
example.c:7:3: warning: initialization makes pointer from integer without a cast [enabled by default]
example.c:7:3: warning: (near initialization for 'p[1][0]') [enabled by default]
example.c:7:3: warning: initialization makes pointer from integer without a cast [enabled by default]
example.c:7:3: warning: (near initialization for 'p[1][1]') [enabled by default]
example.c:7:3: warning: initialization makes pointer from integer without a cast [enabled by default]
example.c:7:3: warning: (near initialization for 'p[1][2]') [enabled by default]
I don't understand the nature of this warning. How do I go about resolving it? Thanks.
Drop the * from BYTE *p[2][4]:
BYTE p[2][4] = {
{0x44,0x58,0x54,0x31},
{0x44,0x58,0x54,0x00}
};
You want a multidimensional array of char: BYTE p[2][4] not a multidimensional array of pointer-to-char.

Resources