Problem with compiling C code - c

I'm using Dev-C++ 4.9.9.2 with MinGW to compile this code:
/* get the information about the group. */
struct group* group_info = getgrnam("PLACEHOLDER");
/* make sure this group actually exists. */
if (!group_info) {
printf("group 'PLACEHOLDER' does not exist.\n");
}
else
{
char** p_member;
printf("Here are the members of group 'PLACEHOLDER':\n");
for (p_member = group_info->gr_mem; *p_member; p_member++)
printf(" %s\n", *p_member);
}
}
I included the following header files:
grp.h
sys/types.h
(got them from glibc 2.13 (maybe this is wrong, but a friend told me this is the right way))
when I try to compile the code, i get a bunch of errors in the headers from glibc, like:
12 C:\glibc-2.9\include\sys\cdefs.h expected constructor, destructor, or type conversion before '(' token
12 C:\glibc-2.9\include\sys\cdefs.h expected `,' or `;' before '(' token
4 C:\glibc-2.9\include\grp.h expected constructor, destructor, or type conversion before '(' token
Edit:
This is the whole Code
#include <grp.h> /* defines 'struct group', and getgrnam(). */
#include <sys/types.h> /* defines 'gid_t', etc. */
BOOL getListOfGroupMembers() {
/* get the information about the "strange" group. */
struct group* group_info = getgrnam("PLACEHOLDER");
/* make sure this group actually exists. */
if (!group_info) {
printf("group 'PLACEHOLDER' does not exist.\n");
}
else
{
char** p_member;
printf("Here are the members of group 'PLACEHOLDER':\n");
for (p_member = group_info->gr_mem; *p_member; p_member++)
{
printf(" %s\n", *p_member);
}
}
return 0;
}
The bool return doesn't make sense at the moment, I want to change that when compiling works.

You can't just bring over a couple of header files from glibc over to mingw on windows. These header files are not self contained, they need a lot of other header files, and probably might even need to be installed on a system (not just refered to in the glibc source folders..)
Besides that, glibc isn't made for windows - these header files are crafted specifically for glibc, and win32 doesn't have the getgrnam() function anyway. (You'd need cygwin, which has its own header files)

There is a missing brace in the lowest for-loop, but maybe it is just a posting error?

I doubt this is the source of the problem, but it looks like your for has a closing bracket }, but lacks and opening one.

Related

Warning: Function must be extern error in C

I am following along a tutorial for C programming in 6502 Assembly and am having a great deal of difficulty on the 3rd step. When compiling my code in the command line, i get these errors:
test4.c(8): Error: '{' expected
test4.c(9): Warning: Function must be extern
test4.c(9): Error: ';' expected
test4.c(13): Error: '}' expected
I am using a program to compile .c files made in code::blocks to .nes files. The current tutorial is having me also make .s assembly file when compiling in the cl65 command line in Windows from the program that is compiling it. Here is the link to the tutorial page i am on:
https://helloacm.com/tutorial-3-c-programming-in-6502-using-assembly/
I have tried many different combinations of code that i can think of to try and get rid of a least some of the problems, but alas to no avail. I am an amateur in C, usually use C++ but i cannot and still trying to figure this out. I was not able to find the "Function must be extern" error anywhere with a quick google search either. Anyone have an idea what's going on?
Here is how i wrote the code in code::blocks:
void main()
{
asm("nop");
}
void testasm()
void main()
{
while(1) {
testasm(); // call the assembled function
}
}
Also, had a really difficult time following along on this particular tutorial part.
Thanks in advance, any help is appreciated on diagnosing the problem!
Perhaps this is what you're after?
void testasm()
{
asm("nop");
}
void main()
{
while(1) {
testasm(); // call the assembled function
}
}
Your code had two main() functions, and a prototype void testasm() with no terminating semicolon.
Alternatively, if testasm is written in assembly, your code should look like this (removing the extra main function):
extern void testasm(); // `extern` not specifically required, but may be for
// your particular compiler
void main()
{
while(1) {
testasm(); // call the assembled function
}
}
You need to be much more careful writing code.

How do I use libdb-4.2 in a FreeBSD 9.1 system?

I'm attempting to write a small program in C that will open and read from a Berkeley 4.2 hash DB on a FreeBSD 9.1 system for testing, but I can't get it to compile. This is the first time I've written anything in C and compiled from a command line so I'm probably missing one thing that'll get it working, I don't know.
After searching all over and looking at documentation and source code on github, this is what I've got so far:
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <db.h>
int main()
{
DB * mydb;
u_int32_t open_flags = DB_RDONLY;
int ret;
ret = db_create(&mydb, NULL, 0);
if (ret != 0) {
printf("Error creating DB structure!");
return 1;
}
ret = mydb->open(mydb, NULL, "bsddb-py", NULL, DB_HASH, open_flags, 0);
if (ret != 0) {
printf("Error opening DB file!");
return 2;
}
mydb->close(mydb, 0);
}
I compile with this:
cc -ldb-4.2 db_test.c
And get this:
db_test.c: In function 'main':
db_test.c:20: error: 'DB_RDONLY' undeclared (first use in this function)
db_test.c:20: error: (Each undeclared identifier is reported only once
db_test.c:20: error: for each function it appears in.)
db_test.c:29: error: 'DB' has no member named 'open'
db_test.c:35: error: too many arguments to function 'mydb->close'
Apparently the compiler is hung up on using Berkeley 1.85 (dbopen and such) and it won't budge?
It looks like #include <db.h> will provide an interface to Berkeley 1.85 because that's what's installed by default on FreeBSD. We have Berkeley 4.2 installed via ports, and to avoid conflicts, the header that interfaces with 4.2 is put elsewhere - I was referencing the right library but not the right header.
So, I changed the include to:
#include <db42/db.h>
...and compiled with...
cc -I/usr/local/include/ -L/usr/local/lib/ -ldb-4.2 db_test.c -o db_test
Running the above source with that modification produced no visible output, which means it worked!
As a newbie to it, BSD is weird.
DB_RDONLY is contained in some header file that you are not #including. That should take care of all the line 20 errors.
Line 29: a DB struct apparently doesn't have a member named open. Recheck the struct/maybe you forgot to include the file that that struct is declared in.
35: Seems like the function close doesn't take 2 arguments. Recheck this in the header file/make sure you included the header file.

C preprocessor redefine conflict dependent on include order

I just had a redefine conflict in the project I'm working on and while tracing down why it's not happening on all platforms (turned out to be to order of includes), I stumbled upon the following behavior which I cannot explain.
1. compiles without warnings
#define LIST_HEAD(a) { int a = 0; }
#include <sys/queue.h>
int main() {
return 0;
}
2. "macro redefined" warning
#include <sys/queue.h>
#define LIST_HEAD(a) { int a = 0; }
int main() {
return 0;
}
I would expect both cases to produce the warning, since there're no checks in <sys/queue.h> that would prevent a redefine.
So why does the first case produces no warning, while the second one does? What I'm missing here?
Btw: I get the same results on my Mac with clang and my Linux box with gcc.
By default, this warning is suppressed in system headers. The code in <sys/queue.h> is considered to come from a system header because sys/queue.h was found by searching a path marked as containing system headers.
So in (2) you see the warning because it is generated within your code, while in (1) the warning is generated within queue.h, and so is suppressed. Add -Wsystem-headers to your compilation options, and you'll see the warning in both cases.

porting C compilation from MinGW to VisualStudio(nmake)

My current job at the university is to port a C program from MinGW (windows) to Visual Studio (nmake).
I have got a valid "makefile.vc" file for a very similar C program.
My approach was to adopt the Makefile (i.e. "makefile.vc") to the program I need to port.
All but four C files seem to compile fine. Those four files have various errors for example, syntax errors and "unknown size".
Should I continue with my approach to change the Makefile or use CMAKE instead of nmake?
Is there a tutorial or any other pointer on porting a C program from MinGW/gcc to nmake?
typedef struct {
A_TypeConverter *converter;
char *domain;
} enumeratorConverterEntry;
static enumeratorConverterEntry enumeratorConverterEntries[]; /* line 186 */
error:
f.c(186) : error C2133: 'enumeratorConverterEntries' : unknown size
typedef struct AsmInstructionInfo {
int flags;
CONST char **argTypes; /* line 7 */
int minArgs;
int maxArgs;
int cArgs;
} AsmInstructionInfo;
error:
fAssemble.c(7) : error C2061: syntax error : identifier 'CONST'
..
/* file fStack.c: */
#ifdef CHECK_ACTIVATION_COUNTS
/* code */
#endif
/* more code */
void fShowStack(l_Interp *interp) { /* line 94 */
l_CallFrame *framePtr;
/* more code */
error:
fStack.c(94) : error C2143: syntax error : missing ')' before '*'
fStack.c(94) : error C2143: syntax error : missing '{' before '*'
fStack.c(94) : error C2059: syntax error : ')'
fStack.c(94) : error C2054: expected '(' to follow 'interp'
static enumeratorConverterEntry enumeratorConverterEntries[]; /* line 186 */
That looks like a valid incomplete, forward declaration of an array, which would be valid syntax, except I think for the static qualifier. I don't have a copy of the 'C' standard in front of me, but reading between the lines on the results of Googling "forward declaration of static array" seems to indicate that an incomplete definition of a static array results in undefined behavior, so Microsoft and GNU are legitimately entitled to do whatever they want with it. GNU accepts it, and Microsoft rejects it. As Mark Wilkins points out you should be make the Microsoft compiler happy by replacing it with:
extern enumeratorConverterEntry enumeratorConverterEntries[]; /* line 186 */
In general it's worth noting that the Microsoft compiler only supports the C89 standard, while the GNU compiler supports portions of the C99 standard, and several of their own extensions, depending on the arguments to the compiler.
The errors in fAssemble.c and fStack.c look like one or more preprocessor files are missing or incomplete. You should search your source to find out where CONST and l_Interp are defined, and then figure out why they are not being picked up in the files where the errors are occurring.
I just now tried out that array declaration with MinGW, and it does compile. To make it link, though, it needs the array to be defined elsewhere. The result is that it appears to be the same as the extern storage class:
extern enumeratorConverterEntry enumeratorConverterEntries[];
I'm not sure if there are other subtleties associated with the original declaration using a static storage class for the global.

uses undefined struct compile error - C

The compiler doesn't know where stat.h is?
Error:
c:\Projects\ADC_HCI\mongoose.c(745) : error C2079: 'st' uses undefined struct '_stat64'
#include <sys/types.h>
#include <sys/stat.h>
static int
mg_stat(const char *path, struct mgstat *stp)
{
struct _stat64 st; //<-- ERROR
int ok;
wchar_t wbuf[FILENAME_MAX];
to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
if (_wstat64(wbuf, &st) == 0) {
ok = 0;
stp->size = st.st_size;
stp->mtime = st.st_mtime;
stp->is_directory = S_ISDIR(st.st_mode);
} else {
ok = -1;
}
return (ok);
}
...downloaded the files straight from the source.
See MSDN: _wstat64 takes a parameter of struct __stat64 (with two underscores). Redeclare your variable st to be of type struct __stat64.
Note that neither _stat64 nor __stat64 is 'standard' in the sense of documented by any standard, such as POSIX. You would normally use struct stat; if you are worried about whether that will work with big files (over 2 GiB), then check what compilation options are required on your platform to obtain 'large file support'. For 64-bit machines and 64-bit compilations (not necessarily Windows 64), you usually don't need to worry. You can often obtain large file support using:
-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
These are at least semi-standardized. Systems such as autoconf detect these things automatically (if you ask them to do so).
Change the _stat64 to stat64. At least in my Linux machines that's the name of the structure. I don't know if it is different in Windows.
I suggest you to sync to SVN trunk.
If you don't have SVN client, simply download two files:
http://mongoose.googlecode.com/svn/trunk/mongoose.h (and .c file too)
The reason is that recently the code was refactored, and CRT _stat function was substituted
with WinAPI one, GetFileAttributesExW().

Resources