I'm new to coding and I don't know what to do with this.
#include <stdio.h>
int get_positive_int(void);
int main(void)
{
int i = get_positive_int();
printf("%i\n", i);
}
int get_positive_int(void)
{
int n;
do
{
n = get_int("Height: ");
}
while (n > 8 || n < 1);
return n;
}
for (int i = 1; i < 9; i++)
{
printf("%i#\n");
}
This is what I got:
$ make mario
clang -fsanitize=signed-integer-overflow -fsanitize=undefined -ggdb3 -O0 -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wshadow mario.c -lcrypt -lcs50 -lm -o mario
mario.c:24:1: error: expected identifier or '('
for (int i = 1; i < 9; i++)
^
1 error generated.
<builtin>: recipe for target 'mario' failed
make: *** [mario] Error 1
It seems you come from a script language background.
In C, all executed code (in contrast to declarations, prototypes, ...) has to be inside a function. It will also only be executed if the funciton is called.
Only main() is called automatically. Everything else has to be in functions which get called (indirectly) from there. (Skipping the discussion of interrrupts and other root context constructs...)
You do have a main() already.
Do you think that your goal can be achieved by moving the problematic code into that?
If not you have to plan which function contains that code and how/when it will be called.
Related
I have to pass a string into a system call in xv6, so I know I have to use argstr(), my question lies with implementing it.
Here is what I have added to sysproc.c:
int sys_hello(char **str)
{
int n = 15;
argstr(n, **str);
for (int i = 0; i < n; i++){
cprintf("%c testplzprint",str[i]);
}
cprintf("Hello World\n");
return 0;
}
I am calling it from testcase.c:
#include "types.h"
#include "stat.h"
#include "user.h"
int main(void)
{
for (int i = 0; i < 5; i++){
hello("itworks");
}
exit();
}
I first implemented it without the testcase and argstr() and just printed hello and it worked well. I'm guessing my problem lies in how I am using argstr(). I really appreciate any help!
Update: sorry for not providing output, here it is right now.
js9313rr#smaug:/tmp/.x2go-js9313rr/media/disk/_cygdrive_C_Users_real0_Desktop_school_SPRING1_352/CSIS352/OS/OS lab 4/xv6-public-master$ make
gcc -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer -fno-stack-protector -fno-pie -no-pie -c -o sysproc.o sysproc.c
sysproc.c: In function \u2018sys_hello\u2019:
sysproc.c:97:13: error: passing argument 2 of \u2018argstr\u2019 makes pointer from integer without a cast [-Werror=int-conversion]
argstr(n, **str);
^
In file included from sysproc.c:3:0:
defs.h:154:17: note: expected \u2018char **\u2019 but argument is of type \u2018char\u2019
int argstr(int, char**);
^~~~~~
cc1: all warnings being treated as errors
<builtin>: recipe for target 'sysproc.o' failed
make: *** [sysproc.o] Error 1
make the hello prototype clear:
Do you want a array of strings ou just a string?
Your sys_hello prototype is wrong, it should be sys_hello(void).
Here an example with an hello syscall taking one string as parameter:
int sys_hello(void)
char *string;
if(argstr(0, &string) < 0){
return -1;
}
cprintf(string);
return 0;
Gcc 11 added -Wvla-parameters to -Wall apparently, now, since I use -Werror always, I get an error like the following:
libtool: compile: mpicc -DHAVE_CONFIG_H -I. -I../../../src/yaxt/src -I../include -I../include -I../../../src/yaxt/src/../include -DgFortran -pthread -g -pipe -O3 -march=native -Wall -Wextra -Wconversion -Wstrict-overflow -Wno-error=unused-function -Wno-error=type-limits -Wno-unknown-pragmas -Werror -Wstrict-aliasing -fsanitize=undefined -MT xt_xmap_dist_dir_common.lo -MD -MP -MF .deps/xt_xmap_dist_dir_common.Tpo -c ../../../src/yaxt/src/xt_xmap_dist_dir_common.c -fPIC -DPIC -o .libs/xt_xmap_dist_dir_common.o
../../../src/yaxt/src/xt_xmap_dist_dir_common.c:239:9: error: mismatch in bound 1 of argument 7 declared as 'int (*)[(long int)(send_size_asize) - 1]' [https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wvla-parameter-Werror=vla-parameter]
239 | int (*send_size)[send_size_asize],
| ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../../../src/yaxt/src/xt_xmap_dist_dir_common.c:62:
../../../src/yaxt/src/xt_xmap_dist_dir_common.h:142:9: note: previously declared as 'int (*)[(long int)(send_size_asize) - 1]'
142 | int (*send_size)[send_size_asize],
| ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
Makefile:836: recipe for target 'xt_xmap_dist_dir_common.lo' failed
But the declaration at src/xt_xmap_dist_dir_common.h:142
PPM_DSO_INTERNAL size_t
xt_xmap_dist_dir_pack_intersections(
enum xt_xmdd_direction target,
size_t num_intersections,
const struct isect *restrict src_dst_intersections,
bool isect_idxlist_delete,
size_t send_size_asize, size_t send_size_idx,
int (*send_size)[send_size_asize],
unsigned char *buffer, size_t buf_size, size_t *ofs, MPI_Comm comm);
matches the definition exactly:
size_t
xt_xmap_dist_dir_pack_intersections(
enum xt_xmdd_direction target,
size_t num_intersections,
const struct isect *restrict src_dst_intersections,
bool isect_idxlist_delete,
size_t send_size_asize, size_t send_size_idx,
int (*send_size)[send_size_asize],
unsigned char *buffer, size_t buf_size, size_t *ofs, MPI_Comm comm)
{
int prev_send_rank = -1;
size_t num_send_indices_requests = 0;
size_t origin = 1 ^ target, ofs_ = *ofs;
int position = 0;
for (size_t i = 0; i < num_intersections; ++i)
{
/* see if this generates a new request? */
int send_rank = src_dst_intersections[i].rank[target];
num_send_indices_requests += send_rank != prev_send_rank;
// pack rank
XT_MPI_SEND_BUF_CONST int *prank
= CAST_MPI_SEND_BUF(src_dst_intersections[i].rank + origin);
if (send_rank != prev_send_rank && prev_send_rank != -1) {
send_size[prev_send_rank][send_size_idx] = position;
ofs_ += (size_t)position;
position = 0;
}
prev_send_rank = send_rank;
xt_mpi_call(MPI_Pack(prank, 1, MPI_INT, buffer+ofs_, (int)(buf_size-ofs_),
&position, comm), comm);
// pack intersection
xt_idxlist_pack(src_dst_intersections[i].idxlist, buffer+ofs_,
(int)(buf_size-ofs_), &position, comm);
if (isect_idxlist_delete)
xt_idxlist_delete(src_dst_intersections[i].idxlist);
}
if (prev_send_rank != -1)
send_size[prev_send_rank][send_size_idx] = position;
*ofs = ofs_ + (size_t)position;
return num_send_indices_requests;
}
If anyone has any suggestion how to get rid of the warning (and allow users to stick to -Wall with gcc 11.1 subsequently), that would be highly appreciated.
I'm aware I can do something along the lines of
#pragma GCC diagnostic ignored "-Wvla-parameter"
but that seems like the wrong approach.
creduce was less painful to get running than I expected.
This seems to be a bad interaction of sanitizer and VLA:
Minimal source to reproduce:
void a(long send_size_asize, int (*)[send_size_asize]);
void a(long send_size_asize, int (*)[send_size_asize]) {}
Command line to check:
gcc-11.1 -c -Wall -Werror -fsanitize=undefined mini.c
Sorry for forgetting to mention -fsanitize, I routinely have that on now, this is the first time it's given me trouble.
Submitted as #10158 to gcc bugzilla.
gcc compiler ignores uninitialized variable warning for debug build. This looks very weird for me, can some one help me to understand this ?
## Program
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int i, max;
int count;
if (argc < 2) {
return -1;
}
max = atoi(argv[1]);
for (i = 0; i < max; i++) {
count++;
}
printf("count is %d\n", count);
return 0;
}
gcc a.c -g -Wall -Werror
No warning
gcc a.c -O3 -Wall -Werror
a.c: In function ‘main’:
a.c:8:9: error: ‘count’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
int count;
^~~~~
cc1: all warnings being treated as errors
gcc version: 7.4.0
Though it may look weird, this behavior is documented for -Wmaybe-uninitialized gcc option:
-Wmaybe-uninitialized
For an automatic (i.e. local) variable, if there exists a path from the function entry to a use of the variable that is initialized, but there exist some other paths for which the variable is not initialized, the compiler emits a warning if it cannot prove the uninitialized paths are not executed at run time.
These warnings are only possible in optimizing compilation, because otherwise GCC does not keep track of the state of variables.
I guess the reason is that the cost of analyzing not initialized variables is too much for not optimizing compilation. That's why it is done only for optimizing one.
I had to create a file.h which I put into my includes/ directory.
I meet a problem when comes time to GCC:
The error I get is:
error: invalid value 'precompiled-header' in '-x precompiled-header'
And I have absolutely no idea about what causes this!
Here is my main, ask me if you need to see more of my code.
I compile with this line of command : gcc -Wall -Wextra -Werror main.c includes/* srcs/* do-op.c
#include "includes/ft.h"
int main(int ac, char **av)
{
int a;
int b;
char c;
(void)ac;
a = ft_atoi(av[1]);
b = ft_atoi(av[3]);
c = av[2][0];
ft_putnbr(ft_do_op(a, b, c));
}
You state that your command to build is:
gcc -Wall -Wextra -Werror main.c includes/* srcs/* do-op.c
That means you're compiling the header files, which you normally should not do. What you should do is tell the compiler where it can find the header files, which is done with the -I (upper case i) option:
gcc -Wall -Wextra -Werror -Iincludes main.c srcs/* do-op.c
The Problem
Note: I originally had this problem in a much larger project; so I pared the code down to the test case you see below.
I cannot figure out how to get the following test code to compile. Specifically, it appears as if the linker cannot find the PCRE library (see below for how PCRE was configured). And this despite the explicit -L/usr/local/lib -lpcre being passed to the linker (PCRE is installed in the /usr/local directory structure).
What am I doing wrong? :-(
The console output is:
$ make
rm -f ./*.o
gcc -ansi -Wall -pedantic-errors -I/usr/local/include -g0 -O3 -static -static-libgcc -march=i686 -malign-double -m128bit-long-double -c main.c -o main.o
gcc -ansi -Wall -pedantic-errors -L/usr/local/lib -lpcre -g0 -O3 -static -static-libgcc -march=i686 -malign-double -m128bit-long-double main.o -o pcre_test_1_i686
main.o:main.c:(.text+0x100): undefined reference to `pcre_compile2'
main.o:main.c:(.text+0x12e): undefined reference to `pcre_study'
main.o:main.c:(.text+0x16e): undefined reference to `pcre_exec'
main.o:main.c:(.text+0x19f): undefined reference to `pcre_copy_substring'
collect2: ld returned 1 exit status
make: *** [all] Error 1
Relevant Files
PCRE Configuration and Compile Environment
./configure --disable-shared --enable-static --disable-cpp --enable-rebuild-chartables --enable-utf8 --enable-unicode-properties --enable-newline-is-any --disable-stack-for-recursion --with-posix-malloc-threshold=2 --with-link-size=4
CC="gcc"
CFLAGS="-g0 -O3 -static -static-libgcc -march=i686 -malign-double -m128bit-long-double"
LD_RUN_PATH="/usr/local/include:/usr/local/lib"
main.c
#define PCRE_STATIC
#include <pcre.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#define OUTPUT_SIZE 12
#define SUBSTRING_SIZE 16
int main(int argc, char *argv[]) {
pcre *re;
pcre_extra *extra;
const char *input = "get food";
const char *pattern = "^\\s*get\\s+(\\w+)\\s*$\0";
int options = PCRE_CASELESS | PCRE_UTF8 | PCRE_UCP;
int error_code = 0;
int error_offset = 0;
const char *compile_error;
const char *study_error;
int output[OUTPUT_SIZE];
char substring[SUBSTRING_SIZE];
int matched = 0;
int is_error = 0;
int index = 0;
for(index = 0; index < OUTPUT_SIZE; index++) {
output[index] = 0;
}
re = pcre_compile2( pattern,
options,
&error_code,
&compile_error,
&error_offset,
NULL );
if(re == NULL) {
fprintf(stderr, "PCRE regular expression error at position %d: %s", error_offset, compile_error);
exit(EXIT_FAILURE);
}
if(error_code == 0) {
extra = pcre_study( re,
0,
&study_error );
}
else {
fprintf(stderr, "PCRE regular expression error at position %d: %s", error_offset, compile_error);
extra = NULL;
}
matched = pcre_exec( re,
extra,
input,
(int)strlen(input),
0, /* Start at the beginning of the string */
0,
output,
OUTPUT_SIZE );
if(matched > 1) {
int status = pcre_copy_substring( input,
output,
matched,
1,
substring,
SUBSTRING_SIZE );
if(status < 0) {
switch(status) {
case PCRE_ERROR_NOMEMORY:
fprintf(stderr, "PCRE substring extraction error: %s", "Buffer too small");
break;
case PCRE_ERROR_NOSUBSTRING:
fprintf(stderr, "PCRE substring extraction error: %s", "Invalid substring number");
break;
}
is_error = 1;
}
}
printf("Capture group 1 is: '%s'\n", substring);
if(is_error) {
printf("There was an error with the pcre_copy_substring() function.\n");
}
return EXIT_SUCCESS;
}
Makefile
PACKAGE = pcre_test
VERSION = 1
# -ansi == ANSI C
# -std=iso9899:199409 == ANSI C w/ Amendment 1
# -std=c99 == ISO C99
GCC_CMD = gcc -ansi -Wall -pedantic-errors
# Generic: i686
# Intel: core2, corei7, corei7-avx
# AMD: k8-sse3, opteron-sse3, athlon64-sse3, amdfam10
ARCH = i686
RELEASE_FILE = $(PACKAGE)_$(VERSION)_$(ARCH)
GCC_OPTIONS = -g0 -O3 -static -static-libgcc -march=$(ARCH) -malign-double -m128bit-long-double
GCC_COMPILE = $(GCC_CMD) -I/usr/local/include $(GCC_OPTIONS)
GCC_LINK = $(GCC_CMD) -L/usr/local/lib -lpcre $(GCC_OPTIONS)
GCC_LINK_ALL = $(GCC_LINK) main.o
all: clean build_main
$(GCC_LINK_ALL) -o $(RELEASE_FILE)
build_main:
$(GCC_COMPILE) -c main.c -o main.o
clean:
rm -f ./*.o
[EDIT]
The Answer Has Been Found!
All external library flags must be listed after all of the object files. Thus, the Makefile should have looked like this:
GCC_LINK = $(GCC_CMD) -L/usr/local/lib $(GCC_OPTIONS)
GCC_LINK_ALL = $(GCC_LINK) main.o -lpcre
Thank you to everyone who responded with answers. :-)
Is it possible the linker is finding a pre-built version of the libpcre.so?
Try the advice from this question:
"specify /usr/local/lib/libpcre.a on the compiler command line ... avoid including -lpcre".