I have several files that I can't get to compile together. It might be how I'm trying to compile them is wrong perhaps. But I just can't get them to work together. I have tried several different changes and have yet to figure out what is causing them to not compile together.
I'm using Windows and Microsoft Visual Studio and developer command prompt as my compiler.
I'm still new to trying to compile several files together.
For the defs.h
file, I'm getting a LNK1107:invalid or corrupt file: cannot read at 0x3E7 error
.
For pack.c
and unpack.c
it has a syntax error saying in line 15 identifier unpack
is missing along with a semicolon and end parenthesis, along with in line 23 same error but identifier pack
instead
I thought for pack and unpack files, given that I'm using typedef
in the defs.h
file, it shouldn't have the identifier problem.
#ifndef DEFS_H
#define DEFS_H
// a structure that contains field widths
typedef struct {
int * fieldWidths; // a pointer to an array of bit field widths (in bits)
int numWidths; // the number of elements in the array (i.e., the number of bit fields)
} sizes;
// a structure that contains an array of ints containing packed data fields
typedef struct {
int * fieldValues; // a pointer to an array of ints containing packed bit fields
int n; // the number of elements in the array
} packed;
// a structure that contains an array of ints containing individual data values (one per int)
typedef struct {
int * values; // a pointer to an array of ints containing values for bit fields (one per element)
int n; // the number of elements in the array
} unpacked;
packed pack(sizes s, unpacked un);
unpacked unpack(sizes s, packed p);
#endif
#include "defs.h"
//The below #define is used to extract bits
//Usage: GETMASK(7, 3) returns value = 00000000_00000000_00000000_11111000
//Usage: GETMASK(7, 0) returns value = 00000000_00000000_00000000_11111111
#define GETMASK(lastbit, firstbit) ( (0xffffffff<<(firstbit)) & (0xffffffff>>(32- (lastbit)-1) ) )
/*
* Pack values into bit fields.
*
* Parameters:
* s - The bit field widths.
* un - The unpacked values.
*
* Returns - packed values.
*/
packed pack(sizes s, unpacked un){
packed p;
int i=0, totalWidth=0, x=0;
int shift;
// Calculating the max number of ints needed to store values
for( i=0; i<s.numWidths; i++){
totalWidth+=s.fieldWidths[i];
p.n = ceil( totalWidth/32.0 );
p.fieldValues = (int*)malloc( sizeof(int)*p.n );
for( i=0; i<p.n; i++)
p.fieldValues[i]=0;
}
shift=32;
for( i=0; i<s.numWidths; i++){
shift -= s.fieldWidths[i];
if( shift < 0 ){
int upperbits = s.fieldWidths[i] + shift;
int part1 = un.values[i] & GETMASK(s.fieldWidths[i]-1, s.fieldWidths[i]-upperbits);
int part2 = un.values[i] & GETMASK(s.fieldWidths[i]-upperbits-1, 0);
p.fieldValues[x++] |= part1;
shift += 32;
p.fieldValues [x] |= (part2 << shift);
continue;
}
p.fieldValues[x] |= (un.values[i] & GETMASK(s.fieldWidths[i]-1, 0)) << shift;
}
return p;
} // end of pack function
#include "defs.h"
/*
* Unpack values from bit fields.
*
* Parameters:
* s - The bit field widths.
* p - The packed values.
*
* Returns - unpacked values.
*/
unpacked unpack(sizes s, packed p){
unpacked up;
int i=0, x;
int index=0, temp;
up.n = s.numWidths;
up.values = (int*)malloc(sizeof(int) * p.n);
x=0;
index=0;
temp = p.fieldValues[0];
for( i=0; i<up.n; i++){
if ( index + s.fieldWidths[i] > 32){
int partb2 = (index+s.fieldWidths[i] - 32);
int partb1 = s.fieldWidths[i] - partb2;
int part1 = temp >> (32-partb1);
up.values[i] = part1 << partb2;
temp = p.fieldValues[++x];
up.values[i] |= temp >> (32-partb2);
temp <<= partb2;
index =partb2;
continue;
}
up.values[i] = temp >> (32-s.fieldWidths[i]);
temp <<= s.fieldWidths[i];
index += s.fieldWidths[i];
}
return up;
} // end of unpack function
I think you're running into trouble because packed
is an attribute that can be applied to structures to indicate that they should be stored with no padding between structure elements. That is more or less consistent with the error messages you indicate.
To prove or disprove this theory, rename packed
to a different name, such as Packed
and see whether that helps. Do it in defs.h
and packed.c
. It helps if the error messages change more than just as a result of the rename operation. If the message said something about packed
before and then says Packed
instead, it hasn't helped. If the error message changes substantially (or is no longer present at all), then the packed
keyword is the trouble.
In GCC, you'd need to use a notation such as __attribute__((packed))
to get a packed structure; you can't use that by accident.
Note that you do not normally compile a header; you compile the source files that use the header. It is not clear why you would be trying to link with the header. You link object files and libraries.
I can confirm that your defs.h
file compiles cleanly on Mac OS X 10.9.2 with GCC 4.8.2. I have a script that does a check compilation on a header to test for self-sufficiency and idempotency. Effectively, it creates a source file (for example, x3981f.c
) containing (in this case):
#include "defs.h" // Self-sufficiency
#include "defs.h" // Idempotency
int main(void) { return 0; } // Non-empty file
It compiles without errors or warnings with:
gcc -c -Wall -Wextra x3981f.c
The pack.c
source file needs #include <math.h>
and both source files need #include <stdlib.h>
added. However, with those additions, the code compiles cleanly using these even more stringent compilation options:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
> -Wold-style-definition -Werror -c pack.c
$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
> -Wold-style-definition -Werror -c unpack.c
$
This practically convinces me that your problem is the name packed
.
OTOH, MSDN shows that you need to use #pragma pack(2)
, for example, to pack structures. That too can't be used by accident. Nevertheless, the code you show compiles cleanly on a Unix system when the missing headers are included. If it does not compile cleanly in MSVC, the problem is inherent in the MSVC environment, and not in C generically.