PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label gcc. Show all posts
Showing posts with label gcc. Show all posts

Sunday, December 11, 2022

[FIXED] Why can I write an expression in an array declaration of a function argument in C?

 December 11, 2022     c, gcc, syntax     No comments   

Issue

Why does the following code compile without warnings or errors?

#include <stdlib.h>
#include <string.h>
#ifdef __GNUC__
__attribute__((__const__))
#endif
int len(char** array) {
    int i;
    for (i = 0; array[i]; i++);
    return i;
}
void inner_len(char** array, int out[len(array)]) {
    int i;
    for (i = 0; i < len(array); i++) {
        out[i] = strlen(array[i]);
    }
}
int main() {
    char* array[] = {
        "hello",
        "world",
        NULL
    };
    int ilen[1];
    inner_len(array, ilen);
}

Especially the function declaration of inner_len is what confuses me the most about this. I have seen gcc provide warnings for wrong array lengths. Is the expression in the function declaration ignored?


Solution

What you did here is to declare a variable length array. If you compile it as ISO C89, you get:

$ gcc --std c89 -pedantic -Wall bla.c
bla.c:9:1: warning: ISO C90 forbids variable length array ‘out’ [-Wvla]
    9 | void inner_len(char** array, int out[len(array)]) {
      | ^~~~

But as C99 there is no warning, since ISO C99 added variable length arrays, refer to, e.g., https://en.wikipedia.org/wiki/Variable-length_array#C99.

Note that out is still an ordinary pointer, as usually in C when you pass an array as argument to a function. And there is also no compile time length check here, since the compiler does run/evaluate the code in the function len(), other than when you'd used a literal like int out[2].



Answered By - Thomas Giesel
Answer Checked By - Mary Flores (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, November 5, 2022

[FIXED] How can I add a default include path for GCC in Linux?

 November 05, 2022     environment-variables, gcc, include, linux     No comments   

Issue

I'd like GCC to include files from $HOME/include in addition to the usual include directories, but there doesn't seem to be an analogue to $LD_LIBRARY_PATH.

I know I can just add the include directory at command line when compiling (or in the makefile), but I'd really like a universal approach here, as in the library case.


Solution

Try setting C_INCLUDE_PATH (for C header files) or CPLUS_INCLUDE_PATH (for C++ header files).

As Ciro mentioned, CPATH will set the path for both C and C++ (and any other language).

More details in GCC's documentation.



Answered By - jcrossley3
Answer Checked By - Katrina (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, September 13, 2022

[FIXED] How to link a program in GCC to prelinked library?

 September 13, 2022     cross-platform, gcc, linker, static-libraries     No comments   

Issue

OK, I have the problem, I do not know exactly the correct terms in order to find what I am looking for on google. So I hope someone here can help me out.

When developing real time programs on embedded devices you might have to iterate a few hundred or thousand times until you get the desired result. When using e.g. ARM devices you wear out the internal flash quite quickly. So typically you develop your programs to reside in the RAM of the device and all is ok. This is done using GCC's functionality to split the code in various sections.

Unfortunately, the RAM of most devices is much smaller than the flash. So at one point in time, your program gets too big to fit in RAM with all variables etc. (You choose the size of the device such that one assumes it will fit the whole code in flash later.)

Classical shared objects do not work as there is nothing like a dynamical linker in my environment. There is no OS or such.

My idea was the following: For the controller it is no problem to execute code from both RAM and flash. When compiling with the correct attributes for the functions this is also no big problem for the compiler to put part of the program in RAM and part in flash. When I have some functionality running successfully I create a library and put this in the flash. The main development is done in the 'volatile' part of the development in RAM. So the flash gets preserved.

The problem here is: I need to make sure, that the library always gets linked to the exact same location as long as I do not reflash. So a single function must always be on the same address in flash for each compile cycle. When something in the flash is missing it must be placed in RAM or a lining error must be thrown.

I thought about putting together a real library and linking against that. Here I am a bit lost. I need to tell GCC/LD to link against a prelinked file (and create such a prelinked file).

It should be possible to put all the library objects together and link this together in the flash. Then the addresses could be extracted and the main program (for use in RAM) can link against it. But: How to do these steps?

In the internet there is the term prelink as well as a matching program for linux. This is intended to speed up the loading times. I do not know if this program might help me out as a side effect. I doubt it but I do not understand the internals of its work.

Do you have a good idea how to reach the goal?


Solution

You are solving a non-problem. Embedded flash usually has a MINIMUM write cycle of 10,000. So even if you flash it 20 times a day, it will last a year and half. An St-Nucleo is $13. So that's less than 3 pennies a day :-). The TYPICAL write cycle is even longer, at about 100,000. It will be a long time before you wear them out.

Now if you are using them for dynamic storage, that might be a concern, depending on the usage patterns.

But to answer your questions, you can build your code into a library .a file easily enough. However, GCC does not guarantee that it links the object code in any order, as it depends on optimization level. Furthermore, only functions that are referenced in a library file is pulled in, so if your function calls change, it may pull in more or less library functions.



Answered By - Richard at ImageCraft
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] how propagate compilation options from a target to all others on Cmake

 September 13, 2022     c, cmake, cross-platform, gcc, target     No comments   

Issue

I'm implementing modern Cmake on a ARM project. I have 3 different CMakeLists:

  • top CMakeLists: contains application files to compile (main.c) + 2 target dependencies (algo and hardware)
target_link_libraries(app_target PUBLIC algo_target hardware_target)
  • algo CMakeLists has only C files which do only computes (algo.c)
  • hardware CMakeLists which compiles all files about hardware dependencies (hardware.c) and compile options depending of the hardware specially -mcpu -mthumb -mfloat-abi -mfpu
target_compile_options(hardware_target -mcpu=${CPU} -mthumb -mfloat-abi=hard -mfpu=${FPU})

The problem is, the compile options are propagate to the top, but not on algo_target. I have the following error:

app uses VFP register arguments, algo.a(algo.cpp.obj) does not

How propagate compilation options on all targets ? I don't want to set compile options in compile option variable, in the future, the application will run on 2 different hardware targets


Solution

Because you do not provide a minimal working example, I might not be able to answer your question fully. However, since CMake is all about targets and dependency management among those targets, I guess that any target that needs some settings/dependencies from another one should depend on that target.

Assume that we have the following directory structure:

.
├── algo
│   ├── CMakeLists.txt
│   ├── include
│   │   └── algo.hpp
│   └── src
│       └── algo.cpp
├── CMakeLists.txt
├── hardware
│   ├── CMakeLists.txt
│   ├── include
│   │   └── hardware.hpp
│   └── src
│       └── hardware.cpp
└── main.cpp

6 directories, 8 files

with the following file contents for algo

# algo/CMakeLists.txt
add_library(algo
  include/algo.hpp
  src/algo.cpp
)
target_include_directories(algo
  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

# if (TARGET hardware)
#   target_link_libraries(algo PRIVATE hardware)
# endif()

/* algo/include/algo.hpp */
#pragma once

double func1(const double);

/* algo/src/algo.cpp */
#include "algo.hpp"

double func1(const double x) {
#ifdef IMPORTANT_DEF
  return 2 * x;
#else
  return x;
#endif
}

for hardware

# hardware/CMakeLists.txt
add_library(hardware
  include/hardware.hpp
  src/hardware.cpp
)
target_include_directories(hardware
  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)
target_compile_definitions(hardware
  PUBLIC
    IMPORTANT_DEF
)

/* hardware/include/hardware.hpp */
#pragma once

#ifdef IMPORTANT_DEF
double func2(const double, const double);
#else
int func2(int, const int);
#endif

/* hardware/src/hardware.cpp */
#include "hardware.hpp"

#ifdef IMPORTANT_DEF
double func2(const double x, const double y) { return x + y; }
#else
int func2(int x, const int y) { return x - y; }
#endif

and, finally, for app

# CMakeLists.txt
cmake_minimum_required(VERSION 3.9)

project(propagate LANGUAGES C CXX)

add_subdirectory(hardware)
add_subdirectory(algo)

add_executable(app main.cpp)
target_link_libraries(app
  PRIVATE
    hardware
    algo
)

/* main.cpp */
#include <iostream>
using namespace std;

#include "hardware.hpp"
#include "algo.hpp"

int main(int argc, char* argv[]) {
  cout << func1(5) << '\n';
  cout << func2(5, 3) << '\n';
  return 0;
}

When we build the above project and run it, we get

./app
5
8

This is because we have not told CMake that algo depends on hardware. When we uncomment the part

# if (TARGET hardware)
#   target_link_libraries(algo PRIVATE hardware)
# endif()

in algo/CMakeLists.txt and rebuild the project, this time we get

./app
10
8

Basically, target_* commands are used to define dependencies that should or should not propagate to the consumers of the targets. Hence, we should make the algo target a consumer of the hardware target.

Please note also that, for the propagation to happen, target_* friends aldo need to populate the INTERFACE_* properties of the target, i.e., target_* commands need to define the properties as either PUBLIC (appearing both in header and implementation files) or INTERFACE (appearing only in header files), but not PRIVATE (appearing only in the implementation files).



Answered By - Arda Aytekin
Answer Checked By - Senaida (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, July 16, 2022

[FIXED] How to remove the warning in gcc 4.6: missing initializer [-Wmissing-field-initializers]?

 July 16, 2022     c, gcc, glib, struct, warnings     No comments   

Issue

The code:

  GValue value = { 0 };

Give the following warning:

missing initializer [-Wmissing-field-initializers]

I know that's a gcc's BUG; but is there some trick to remove it? really not nice see such unreal warnings. But I don't want power off the warning because it will hidden real warnings from me too. A sorry, but I can't update my gcc to 4.7(where looks like it was fixed) version, yet.


Solution

Use G_VALUE_INIT to initialize GValue-s. Their (private) structure is in /usr/include/glib-2.0/gobject/gvalue.h which #define G_VALUE_INIT appropriately.

I strongly disagree with your assessment that it is GCC's bug. You ask to be warned if a field is not explicitly initialized with -Wmissing-field-initializers and you get the warning you deserve.

Sadly G_VALUE_INIT is not documented, but it is here. Code with

GValue value = G_VALUE_INIT;

There is no universal solution to never get the warning about missing field initialization if -Wmissing-field-initializers is asked. When you ask for such a warning, you require the compiler to warn of every incomplete initializers. Indeed, the standard requires than all the non-explicitly initialized struct fields be zeroed, and gcc obeys the standard.

You could use diagnostic pragmas like

#pragma GCC diagnostic ignored "-Wmissing-field-initializers"

But my feeling is that you should code with care, and explicitly initialize all the fields. The warning you get is more a coding style warning (maybe you forgot a field!) than a bug warning.

I also believe that for your own (public) struct you should #define an initializing macro, if such struct are intended to be initialized.



Answered By - Basile Starynkevitch
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Wednesday, July 6, 2022

[FIXED] How to visualize the pointers in the code snippet?

 July 06, 2022     c, dereference, gcc, pass-by-reference, pointers     No comments   

Issue

I am finding it difficult to visualize this piece of code. I cannot seem to find the ans to this.

I did get the ans for

printf("**r = %d\n",**r);
printf("**s = %d\n",**s);

but other variables are not matching the ans. Please help.

int f(int ** r, int ** s) {
    int temp = ** r;
    int temp2 = **s;
    int * z = *r;
    *r = *s;
    *s = z;

    printf("**r = %d\n",**r);
    printf("**s = %d\n",**s);
    *z += 3;
    **s -= 8;
    **r -= 19;

    return temp + temp2;
}

int main(void) {
    int a = 80;
    int b = 12;
    int * p = &a;
    int * q = &b;
    int x = f(&p, &q);

    printf("x = %d\n", x);
    printf("*p = %d\n", *p);
    printf("*q = %d\n", *q);
    printf("a = %d\n", a);
    printf("b = %d\n", b);

    return EXIT_SUCCESS;
}

Expected output:

**r = 12
**s=80
x=92
*p=-7
*q=75
a=75
b=-7 

Solution

In this declaration the pointers p and q are passed by reference to the function f.

int x = f(&p, &q);

The pointer p points to the variable a and the pointer q points to the variable b.

int a = 80;
int b = 12;
int * p = &a;
int * q = &b;

Within the function f declared like

int f(int ** r, int ** s);

the pointer r points to the pointer p and the pointer s points to the pointer q.

Correspondingly in these declarations

int temp = ** r;
int temp2 = **s;

the variable temp is initialized by the value of variable a and the variable temp2 is initialized by the value of the variable b.

You van imaging these declaration like

int temp = a;
int temp2 = b;

In this code snippet

int * z = *r;
*r = *s;
*s = z;

there are in fact swapped the the pointers p and q pointed to by the pointers r and s. That is after this code snippet the pointer r now points to the pointer q and the pointer s points to the pointer p.

You can imaging this like

*r = q;
*s = p;

The intermediate variable z

int * z = *r;

gets the value of the pointer p.

You can imaging this like

int * z = p;

This statement

*s = z;

did not change the value pointed to by s because before this statement the variable s already pointed to p due to preceding swapping the pointed values of the pointer r and the pointer s.

So these calls of printf

printf("**r = %d\n",**r);
printf("**s = %d\n",**s);

correspondingly will output the value of b and the value of a.

That is the output will be

**r = 12
**s = 80

As the pointer z has the value of the pointer p then after this statement

*z += 3;

the variable a will be increased by 3 and becomes equal to 83.

In these statements

**s -= 8;
**r -= 19;

the variable a will be decrease by 8 and becomes equal to 75 And the variable b is decreased by 19 and becomes equal to -7.

At last the function returns the sum of the initial values of the variables a and b

return temp + temp2;

that is 92.

In these statements in main

printf("x = %d\n", x);
printf("*p = %d\n", *p);
printf("*q = %d\n", *q);
printf("a = %d\n", a);
printf("b = %d\n", b);

there is outputted the value returned by the function f

printf("x = %d\n", x);

that is 92.

As the pointers p and q were swapped in the function then now the pointer p points to b and the pointer q points to a.

printf("*p = %d\n", *p);
printf("*q = %d\n", *q);

So these statements output

*p = -7
*q = 75

And these statements

printf("a = %d\n", a);
printf("b = %d\n", b);

outputs the new values of a and b themselves that is

a = 75
b = -7

As for this statements

printf("**r = %d\n",**r);
printf("**s = %d\n",**s);

then for example the expression *r points to the pointer p. So dereferencing the pointer p like *p that is the same as *( *r ) you will get the lvalue of the variable a.



Answered By - Vlad from Moscow
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How do I pass a temporary object as a non-const reference into a member function?

 July 06, 2022     c++, gcc, lvalue-to-rvalue, pass-by-reference, temporary-objects     No comments   

Issue

We are creating a class designed to send information out from the current module (the specifics are not relevant to this question). An object of this type is created and populated with a portion of the data that needs to be sent, and then passed into a (different class) member function. That function provides the object with the rest of the data, and then triggers the send, via a call in the object itself. Because the information being passed in is dynamic, the intention is that the information transfer object be a temporary one, created with the latest data. The design we lined out is in the distilled source code below, but gcc/C++ does not allow this, giving the error shown.

The question is, how can we accomplish the intended behavior, using temporary objects (nice for avoiding memory leaks) that can be modified and used by the called function?

gcc compiler error:

infoxfer.cpp: In function ‘int main()’:
infoxfer.cpp:54:43: error: cannot bind non-const lvalue reference of type ‘XferInfo&’ to an rvalue of type ‘XferInfo’
   51 |     callee.doSomething("Something param", XferInfo("from main()"));
      |                                           ^~~~~~~~~~~~~~~~~~~~~~~
infoxfer.cpp:36:62: note:   initializing argument 2 of ‘void Callee::doSomething(const string&, XferInfo&)’
   33 |     void doSomething(const string& somethingParam, XferInfo& xferInfo)
      |                                                    ~~~~~~~~~~^~~~~~~~

The distilled sample code:
infoxfer.cpp:

#include <iostream>
using std::cout;
using std::endl;

#include <string>
using std::string;

class XferInfo
{
private:
    const string mCallerInfo;
    string mCalleeInfo;

public:
    XferInfo(const string& callerInfo) : mCallerInfo(callerInfo)
    {}

    void setCalleeInfo(const string& calleeInfo)
    {
        mCalleeInfo = calleeInfo;
    }

    void sendData()
    {
        // simulate sending data
        cout << mCallerInfo << " | " << mCalleeInfo << endl;
    }
};

class Callee
{
public:
    void doSomething(const string& somethingParam, XferInfo& xferInfo)
    {
        // complete data for xfer
        xferInfo.setCalleeInfo(somethingParam);

        // simulate doing something
        cout << "do something" << endl;

        // send the complete info
        xferInfo.sendData();
    }
};

int main()
{
    cout << "start" << endl;

    Callee callee;
    callee.doSomething("Something param", XferInfo("from main()"));

    cout << "end" << endl;

    return 0;
}

Solution

As mentioned in the comments, you could simply change your doSomething function to accept an rvalue reference to the passed XferInfo object (using the double &&):

    void doSomething(const string& somethingParam, XferInfo&& xferInfo)
    {
        // complete data for xfer
        xferInfo.setCalleeInfo(somethingParam);
        // ... and so forth ...

From the linked cppreference page:

Rvalue references can be used to extend the lifetimes of temporary objects (note, lvalue references to const can extend the lifetimes of temporary objects too, but they are not modifiable through them)



Answered By - Adrian Mole
Answer Checked By - Marie Seifert (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, June 26, 2022

[FIXED] How to force Werror=declaration-after-statement with -std=c99 in clang

 June 26, 2022     c, c99, clang, compiler-errors, gcc     No comments   

Issue

I would like to have compiler throw an error every time there is a declaration after statement because that is the coding style I want to enforce, but I also want to compile with -std=c99 since I use some of the specific c99 features.

The problem is that in c99 declarations are allowed anywhere in the code, not just at the beginning of a block.

Take a look at the following program:

// prog.c
#include <stdio.h>

int main(void)
{
    printf("hello world\n");
    int i = 0;

    return 0;
}

If I compile this code with gcc like this:

gcc -std=c99 -Werror=declaration-after-statement prog.c

it throws the following error:

prog.c: In function ‘main’:
prog.c:6:9: error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement]
    6 |         int i = 0;
      |         ^~~
cc1: some warnings being treated as errors

This is the behavior I would like to have when compiling with clang, but clang behaves differently.

If I compile the same code with clang like this:

clang -std=c99 -Werror=declaration-after-statement prog.c

it throws no errors.

Only if I compile the code with clang like this it throws the error I want:

clang -std=c90 -Werror=declaration-after-statement prog.c

prog.c:6:6: error: ISO C90 forbids mixing declarations and code [-Werror,-Wdeclaration-after-statement]
        int i = 0;
            ^
1 error generated.

But this is not good for me because I need to use -std=c99.

Is it possible to force -Werror=declaration-after-statement along with -std=c99 when compiling with clang?


Solution

Looking at the source code of clang it seems like not supported.

The diagnostic is defined in clang/include/clang/Basic/DiagnosticSemaKind.td

def ext_mixed_decls_code : Extension<
  "ISO C90 forbids mixing declarations and code">,
  InGroup<DiagGroup<"declaration-after-statement">>;

And its only usage is in clang/lib/Sema/SemaStmt.cpp

StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
                                   ArrayRef<Stmt *> Elts, bool isStmtExpr) {
  const unsigned NumElts = Elts.size();

  // If we're in C89 mode, check that we don't have any decls after stmts.  If
  // so, emit an extension diagnostic.
  if (!getLangOpts().C99 && !getLangOpts().CPlusPlus) {
    // Note that __extension__ can be around a decl.
    unsigned i = 0;
    // Skip over all declarations.
    for (; i != NumElts && isa<DeclStmt>(Elts[i]); ++i)
      /*empty*/;

    // We found the end of the list or a statement.  Scan for another declstmt.
    for (; i != NumElts && !isa<DeclStmt>(Elts[i]); ++i)
      /*empty*/;

    if (i != NumElts) {
      Decl *D = *cast<DeclStmt>(Elts[i])->decl_begin();
      Diag(D->getLocation(), diag::ext_mixed_decls_code); // <-- here
    }
  }
  ...

Note the !getLangOpts().C99 in the if. The diagnose code will never execute with a standard above c90.

Well one thing you can surely try is build clang by yourself and delete that part of the if so end up with if (!getLangOpts().CPlusPlus).

I tried and it worked for me.

You can configure the clang build with cmake -G "Ninja" -DCMAKE_BUILD_TYPE="Release" -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_TARGETS_TO_BUILD="X86" -DCMAKE_C_COMPILER="/usr/bin/gcc" -DCMAKE_CXX_COMPILER="/usr/bin/g++" -DLLVM_PARALLEL_LINK_JOBS=2 -DLLVM_OPTIMIZED_TABLEGEN=ON path/to/llvm-project/llvm



Answered By - Eraklon
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] Why does the compiler is giving me this: undefined reference to function?

 June 26, 2022     c, compiler-errors, declaration, function, gcc     No comments   

Issue

Ok I have been trying to figure this out for 3 hours and I have search a bunch of stack overflow questions and answers but I have this same error:

/usr/bin/ld: /tmp/ccXbXNRV.o: in function 'main':
main.c:(.text+0x5a): undefined reference to 'plus'
/usr/bin/ld: main.c:(.text+0x67): undefined reference to `minus'
collect2: error: ld returned 1 exit status

And I cant figure this out because my code doesn't seem that he is the problem

main.c:

#include <stdio.h>
#include "funcs.c"

int main()
{
    int z = 0;
    int wh = 1;
    while (wh == 1)
    {
        printf("What you want?\n1-Plus\n2-Minus\n");
        scanf("%d", &z);
        if (z == 1)
        {
            plus();
        }
        if (z == 2)
        {
            minus();
        }
    }
    printf("The program ended\n");

    return 0;
}

funcs.c

#include <stdio.h>

inline void plus(void)
{
    int a = 0;
    int b = 0;
    printf("Pls insert a numb\n");
    scanf("%d", &a);
    printf("Pls insert a numb\n");
    scanf("%d", &b);
    a = a + b;
    printf("The result is: %d\n", a);
}

inline void minus(void)
{
    int a = 0;
    int b = 0;
    printf("Pls insert a numb\n");
    scanf("%d", &a);
    printf("Pls insert a numb\n");
    scanf("%d", &b);
    a = a - b;
    printf("The result is: %d\n", a);
}

help.h

extern int a;
extern int b;
extern int z;
extern int wh;
inline void minus(void);
inline void plus(void);

I have try to compile it with this command gcc funcs.c main.c I know that is a simple program but I really want to learn c

If you could help I would be very thankful!


Solution

You can fix this by doing three things:

  1. Don't include a .c file. You're already providing it to gcc on the command line.
  2. Include help.h in files where you use those functions.
  3. Not using inline. You can't use inline when the caller and callee are in different translation units.

main.c:

#include <stdio.h>
// #include "funcs.c"
#include "help.h"

int main()
{
    int z = 0;
    int wh = 1;
    while (wh == 1)
    {
        printf("What you want?\n1-Plus\n2-Minus\n");
        scanf("%d", &z);
        if (z == 1)
        {
            plus();
        }
        if (z == 2)
        {
            minus();
        }
    }
    printf("The program ended\n");

    return 0;
}

funcs.c

#include <stdio.h>

void plus(void)
{
    int a = 0;
    int b = 0;
    printf("Pls insert a numb\n");
    scanf("%d", &a);
    printf("Pls insert a numb\n");
    scanf("%d", &b);
    a = a + b;
    printf("The result is: %d\n", a);
}

void minus(void)
{
    int a = 0;
    int b = 0;
    printf("Pls insert a numb\n");
    scanf("%d", &a);
    printf("Pls insert a numb\n");
    scanf("%d", &b);
    a = a - b;
    printf("The result is: %d\n", a);
}

help.h:

extern int a;
extern int b;
extern int z;
extern int wh;
void minus(void);
void plus(void);

Compile and run like so:

$ gcc -Wall -Werror funcs.c main.c
$ ./a.out 
What you want?
1-Plus
2-Minus
^C

Other thoughts:

extern int a;
extern int b;
extern int z;
extern int wh;

You're already declaring these variables locally. This is unneeded. The extern keyword tells the compiler that these variables are defined in another translation unit that it can't see. This isn't true, so you should just remove these.



Answered By - Nick ODell
Answer Checked By - Cary Denson (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to determine which compiler flag/option causes "--p" to be passed to assembler?

 June 26, 2022     compiler-errors, gcc, gnu-assembler, musl, riscv     No comments   

Issue

I am trying to build the musl C library using a custom risc-v toolchain that uses GNU gcc version 8.1.0, GNU assembler version 2.34.

The error I get is the following:

home/guillermo/toolchain/as: invalid option -- 'p'

However, using the verbose flags for gcc and as the last call to the assembler is as follows (which includes NO such "--p" flag):

/home/guillermo/toolchain/as -v -I ./arch/riscv64 -I ./arch/generic -I obj/src/internal -I ./src/include -I ./src/internal -I obj/include -I ./include -I /home/guillermo/toolchain/library/common --traditional-format -fpic -march=rv64imafdc -mabi=lp64d --noexecstack -o obj/crt/Scrt1.o

The invocation of gcc before that was:

 /home/guillermo/toolchain/riscv64-gcc -nostdinc -v -I ./arch/riscv64 -I ./arch/generic -I obj/src/internal -I ./src/include -I ./src/internal -I obj/include -I ./include -I /home/guillermo/toolchain/library/common -D _XOPEN_SOURCE=700 -D CRT crt/Scrt1.c -quiet -dumpbase Scrt1.c -march=rv64imafdc -mabi=lp64d -auxbase-strip obj/crt/Scrt1.o -g -Os -Werror=implicit-function-declaration -Werror=implicit-int -Werror=pointer-sign -Werror=pointer-arith -Wno-tautological-compare -Wall -std=c99 -version -ffreestanding -fexcess-precision=standard -frounding-math -fno-unwind-tables -fno-asynchronous-unwind-tables -ffunction-sections -fdata-sections -fPIC -fno-stack-protector -o - |

Any help would be greatly appreciated as to what compiler flag could be causing "--p" to be passed to the assembler.


Solution

-fpic is an option for the compiler in particular. It has no special meaning to the assembler, which treats it the same as -f -p -i -c.



Answered By - Joseph Sible-Reinstate Monica
Answer Checked By - Timothy Miller (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How can I ignore GCC compiler 'pedantic' errors in external library headers?

 June 26, 2022     compiler-construction, compiler-errors, gcc     No comments   

Issue

I recently added -pedantic and -pedantic-errors to my make GCC compile options to help clean up my cross-platform code. All was fine until it found errors in external-included header files. Is there a way to turn off this error checking in external header files, i.e.:

Keep checking for files included like this:

#include "myheader.h"

Stop checking for include files like this:

#include <externalheader.h>

Here are the errors I am getting:

g++ -Wall -Wextra -Wno-long-long -Wno-unused-parameter -pedantic --pedantic-errors
-O3 -D_FILE_OFFSET_BITS=64 -DMINGW -I"freetype/include" -I"jpeg" -I"lpng128" -I"zlib"
-I"mysql/include" -I"ffmpeg/libswscale" -I"ffmpeg/libavformat" -I"ffmpeg/libavcodec"
-I"ffmpeg/libavutil" -o omingwd/kguimovie.o -c kguimovie.cpp

In file included from ffmpeg/libavutil/avutil.h:41,
             from ffmpeg/libavcodec/avcodec.h:30,
             from kguimovie.cpp:44:
ffmpeg/libavutil/mathematics.h:32: error: comma at end of enumerator list
In file included from ffmpeg/libavcodec/avcodec.h:30,
             from kguimovie.cpp:44:
ffmpeg/libavutil/avutil.h:110: error: comma at end of enumerator list
In file included from kguimovie.cpp:44:
ffmpeg/libavcodec/avcodec.h:277: error: comma at end of enumerator list
ffmpeg/libavcodec/avcodec.h:303: error: comma at end of enumerator list
ffmpeg/libavcodec/avcodec.h:334: error: comma at end of enumerator list
ffmpeg/libavcodec/avcodec.h:345: error: comma at end of enumerator list
ffmpeg/libavcodec/avcodec.h:2249: warning: `ImgReSampleContext' is deprecated
(declared at ffmpeg/libavcodec/avcodec.h:2243)
ffmpeg/libavcodec/avcodec.h:2259: warning: `ImgReSampleContext' is deprecated
(declared at ffmpeg/libavcodec/avcodec.h:2243)
In file included from kguimovie.cpp:45:
ffmpeg/libavformat/avformat.h:262: error: comma at end of enumerator list
In file included from ffmpeg/libavformat/rtsp.h:26,
             from ffmpeg/libavformat/avformat.h:465,
             from kguimovie.cpp:45:
ffmpeg/libavformat/rtspcodes.h:38: error: comma at end of enumerator list
In file included from ffmpeg/libavformat/avformat.h:465,
             from kguimovie.cpp:45:
ffmpeg/libavformat/rtsp.h:32: error: comma at end of enumerator list
ffmpeg/libavformat/rtsp.h:69: error: comma at end of enumerator list

Solution

You could fix the headers and submit a patch to FFmpeg; compatibility with -pedantic is a worthy goal, so I'm sure they'd consider it, especially if it just involved removing trailing commas and suchlike.



Answered By - Mike F
Answer Checked By - David Marino (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to fix "Qt requires a C++17 compiler" error?

 June 26, 2022     cgal, compiler-errors, gcc, macos, qt     No comments   

Issue

I installed with brew the CGAL C++ library. After doing cmake . in the first basic example , I do make and I got a sequence of errors, the first one and most important is:

/usr/local/include/QtCore/qglobal.h:96:6: error: "Qt requires a C++17 compiler"
#    error "Qt requires a C++17 compiler"
     ^

which means that I need a way to tell Qt to use a C++17 compiler. How can I fix this? I'm an engineer, and I've never faced a similar issue before. There have been similar questions before (like this) but they're about Windows.

I'm using a MacOS BigSur, 11.6.2. and gcc --version returns

Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 13.0.0 (clang-1300.0.29.30)
Target: x86_64-apple-darwin20.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

Solution

Actually, you will need to tell cmake to activate c++17 support in the compiler commands it generates. By default, Apple clang was chosen, and that comes with an earlier default std support.

cmake -DCMAKE_CXX_FLAGS="-std=c++17" .

If for whatever reason you intended to compile with the gcc wrapper or some other compiler, you can let cmake know:

cmake -DCMAKE_CXX_COMPILER="gcc" -DCMAKE_CXX_FLAGS="-std=c++17" .


Answered By - Richard Barber
Answer Checked By - Robin (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] how to succesfully compile python 3.x

 June 26, 2022     compiler-errors, gcc, python, python-3.7, runpy     No comments   

Issue

Upon attempting to compile python 3.7 I hit Could not import runpy module:

jeremyr@b88:$ wget https://www.python.org/ftp/python/3.7.3/Python-3.7.3.tar.xz
....
jeremyr@b88:~/Python-3.7.3$ ./configure --enable-optimizations    
jeremyr@b88:~/Python-3.7.3$ make clean 
jeremyr@b88:~/Python-3.7.3$ make -j32 
.... 

gcc -pthread     -Xlinker -export-dynamic -o Programs/_testembed Programs/_testembed.o libpython3.7m.a -lcrypt -lpthread -ldl  -lutil   -lm  
./python -E -S -m sysconfig --generate-posix-vars ;\
if test $? -ne 0 ; then \
    echo "generate-posix-vars failed" ; \
    rm -f ./pybuilddir.txt ; \
    exit 1 ; \
fi
Could not import runpy module
Traceback (most recent call last):
  File "/home/jeremyr/Python-3.7.3/Lib/runpy.py", line 15, in <module>
    import importlib.util
  File "/home/jeremyr/Python-3.7.3/Lib/importlib/util.py", line 14, in <module>
    from contextlib import contextmanager
  File "/home/jeremyr/Python-3.7.3/Lib/contextlib.py", line 4, in <module>
    import _collections_abc
SystemError: <built-in function compile> returned NULL without setting an error
generate-posix-vars failed
Makefile:603: recipe for target 'pybuilddir.txt' failed
make[1]: *** [pybuilddir.txt] Error 1
make[1]: Leaving directory '/home/jeremyr/Python-3.7.3'
Makefile:531: recipe for target 'profile-opt' failed
make: *** [profile-opt] Error 2

jeremyr@88:~/Python-3.7.3$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 8.11 (jessie)
Release:    8.11
Codename:   jessie

jeremyr@88:~/Python-3.7.3$ gcc --version 
gcc (Debian 4.9.2-10+deb8u2) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

jeremyr@88:~/Python-3.7.3$ sudo apt upgrade gcc
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Calculating upgrade... gcc is already the newest version.

jeremyr@b88:~/Python-3.7.3$ echo $PYTHONPATH

Any advice on how to overcome this and install python3.7 appreciated.

Edit - the solution listed below seems to work for various other python versions, so I changed title to python 3.x from 3.7


Solution

It seems the enable-optimizations was the problem,

jeremyr@b88:~/Python-3.7.3$ ./configure   
jeremyr@b88:~/Python-3.7.3$ make clean 

takes care of it in my case.



Answered By - jeremy_rutman
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] how to solve: error: global qualification of class name is invalid before '{' token

 June 26, 2022     c++, compiler-errors, gcc, namespaces     No comments   

Issue

I'm trying to build https://android.googlesource.com/device/generic/vulkan-cereal but have run into an error that seems to only happen with GCC (v8.3 is what I have to work with).

There are related questions, but I still don't understand what's going on well enough to fix the issue:

  • Global qualification in base specifier
  • Global qualification in a class declarations class-head

The code:

https://android.googlesource.com/device/generic/vulkan-cereal/+/refs/heads/master/stream-servers/vulkan/vk_fn_info.h

#define REGISTER_VK_FN_INFO(coreName, allNames)                 \
    struct coreName;                                            \
    template <>                                                 \
    struct ::vk_util::vk_fn_info::GetVkFnInfo<coreName> {       \
        static constexpr auto names = std::make_tuple allNames; \
        using type = PFN_vk##coreName;                          \
    };

REGISTER_VK_FN_INFO(GetPhysicalDeviceProperties2,
                    ("vkGetPhysicalDeviceProperties2KHR", "vkGetPhysicalDeviceProperties2"))

The Error:

vulkan-cereal/stream-servers/vulkan/vk_fn_info.h:31:57: error: global qualification of class name is invalid before '{' token
     struct ::vk_util::vk_fn_info::GetVkFnInfo<coreName> {       \
                                                         ^

/vulkan-cereal/stream-servers/vulkan/vk_fn_info.h:36:1: note: in expansion of macro 'REGISTER_VK_FN_INFO'
 REGISTER_VK_FN_INFO(GetPhysicalDeviceProperties2,
 ^~~~~~~~~~~~~~~~~~~

What can I do to get this to build?


Solution

The global qualifier is the two colons at the front:

struct ::vk_util::vk_fn_info::GetVkFnInfo<coreName> {
       ^^

But the answer was to remove all qualifiers:

struct ::vk_util::vk_fn_info::GetVkFnInfo<coreName> {
       ^^^^^^^^^^^^^^^^^^^^^^^

So it becomes:

#define REGISTER_VK_FN_INFO(coreName, allNames)                 \
    struct coreName;                                            \
    template <>                                                 \
    struct GetVkFnInfo<coreName> {                              \
        static constexpr auto names = std::make_tuple allNames; \
        using type = PFN_vk##coreName;                          \
    };

The trick was that this revealed knock-on errors caused by the macro being improperly used outside the namespaces in another file:

vk_util_unittest.cpp:28:25: error: expected constructor, destructor, or type conversion before '(' token
 REGISTER_VK_FN_INFO_TEST(GfxstreamTestFunc, ("vkGfxstreamTestFunc", "vkGfxstreamTestFuncGOOGLE",

The final change required fixing the namespaces in vk_util_unittest.cpp so that they matched the ones in vk_fn_info.h

As an alternative, I found that the macro could be used outside the namespace as long as it was fully qualified (excluding the invalid global qualification):

#define REGISTER_VK_FN_INFO_EXTERN(coreName, allNames)          \
    struct coreName;                                            \
    template <>                                                 \
    struct vk_util::vk_fn_info::GetVkFnInfo<coreName> {         \
        static constexpr auto names = std::make_tuple allNames; \
        using type = PFN_vk##coreName;                          \
    };

But this prevented it from being used within the namespace. Two separate macros would be needed to satisfy use within and without the namespace.



Answered By - jpx
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, April 28, 2022

[FIXED] How can I make GCC/Clang warn about the use of uninitialized members?

 April 28, 2022     c++, clang, gcc, warnings     No comments   

Issue

I am compiling the code behind

class Test {
public:
    Test() {}

    int k;
};

int main() {
  Test t;
  std::cout << t.k << "\n";
}

like

g/clang++ main.cpp -Wall -Wextra --std=c++14 -o exe; ./exe

Why neither of the compilers does not warn me about indeterminate value of the integer is not it a very serious potential bug? How to enable a warning for indeterminate initializations?


Solution

For this example, GCC gives me the desired warning when I give it -O1 (or higher).

Presumably whatever mechanism it uses to detect this is tied into the optimisation effort level somehow. It's a notoriously hard thing to do.

Ensure that you heed your release-build warnings as well as debug-build warnings.



Answered By - Lightness Races in Orbit
Answer Checked By - Timothy Miller (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] What is the meaning of the GCC warning "case label value exceeds maximum value for type"?

 April 28, 2022     c, gcc, switch-statement, warnings     No comments   

Issue

My code looks like this:

char * decode_input(char ch)
{
        switch(ch) {
                case 'g':
                        return "get";
                        break;
                case KEY_F(9):
                        return "quit";
                        break;
                default:
                        return "unknown";
                        break;
        }
}

Any clues?


Solution

A char is a number between -128 and 127. KEY_F(9) probably is a value outside of that range.

Use:

  • unsigned char, or
  • int, or
  • (char) KEY_F(9)

Or even better, use a debugger and determine sizeof(KEY_F(9)) to make sure it's a byte and not a short.



Answered By - razzed
Answer Checked By - Pedro (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How can I ignore all warnings from included headers in clang/gcc?

 April 28, 2022     clang, gcc, warnings     No comments   

Issue

I want to use #pragma clang diagnostic push to ignore warnings from some included header files. So I write this:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wall"
#include "SpinGenApi/SpinnakerGenApi.h"
#include "Spinnaker.h"
#pragma clang diagnostic pop

But still the compiler prints warnings when compiling the file with this code. What do I need to change so that all warnings are ignored for these headers?


Solution

The answer seems to be in this case that -Wall contrary to its name did not include the warnings which I wanted to suppress. I added #pragma clang diagnostic ignored "-Weverything" as well and they went away.



Answered By - oarfish
Answer Checked By - Katrina (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How do I get rid of the following sign-conversion warning?

 April 28, 2022     c, gcc, unsigned, warnings     No comments   

Issue

I am getting the following warning whenever the function initSetArray() is called :

error: conversion to ‘long unsigned int’ from ‘int’ may change the sign of the result [-Werror=sign-conversion]
  setarray = (set*)malloc(sizeof(set) * number_of_sets);   

The function initSetArray simply initializes the setarray.

void initSetArray(set *setarray, int number_of_sets, int number_of_blocks)
{
    setarray = (set*)malloc(sizeof(set) * number_of_sets);
}

I have defined two structures which are used in the helper function defined above:

typedef struct{
    uint64_t tag;   // For identifying the block
    uint8_t valid;  // Valid bit for the block
    uint8_t dirty;  // Dirty bit for the block
} block;

typedef struct{
    uint64_t index; // For identifying the set
    block* way;
} set;

I cannot exactly find out which variable is of type "long unsigned int". What can I do to resolve this issue?


Solution

In this statement

setarray = (set*)malloc(sizeof(set) * number_of_sets);

the variable number_of_sets is an integer (int), and because it is used in an expression with sizeof (size_t), the value is converted to match.

size_t is usually an unsigned long. If you don't like the warning, this would fix it:

setarray = (set*)malloc(sizeof(set) * (size_t) number_of_sets);


Answered By - Thomas Dickey
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] Where did sincos go? (gcc c)

 April 28, 2022     c, gcc, math.h, warnings     No comments   

Issue

Couple days ago it was working fine, but trying to use again today, my code editor cannot find sincos anymore and GCC throws me a warning that it cannot find sincos when compiling.

Here's the code:

// file: main.c 

#include <math.h>                                                                                                  
int main() {                                                                                                                         
    double sin, cos;                                                                                                     
    sincos(0.0, &sin, &cos);                                                                                             
    return 0;                                                                                                    
}        

Using gcc:

$ gcc main.c -lm

   x.c: In function ‘main’:
x.c:5:2: warning: implicit declaration of function ‘sincos’ [-Wimplicit-function-declaration]
    5 |  sincos(0.0, &sin, &cos);
      |  ^~~~~~
x.c:5:2: warning: incompatible implicit declaration of built-in function ‘sincos’
x.c:2:1: note: include ‘<math.h>’ or provide a declaration of ‘sincos’
    1 | #include <math.h>
  +++ |+#include <math.h>
    2 |

It says I should include math.h yet I do. It says it can't find sincos yet it compiles and runs fine. I'm just annoyed by those warnings. Anyone knows what's wrong?


Solution

Add the following to the top of the file to enable the gnu extension:

#define _GNU_SOURCE
#include <math.h>

This will prevent the warnings. Note that this is a glibc extension and not part of the C standard.



Answered By - Tom Karzes
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] Why do I get a warning every time I use malloc?

 April 28, 2022     c, gcc, malloc, sizeof, warnings     No comments   

Issue

If I use malloc in my code:

int *x = malloc(sizeof(int));

I get this warning from gcc:

new.c:7: warning: implicit declaration of function ‘malloc’  
new.c:7: warning: incompatible implicit declaration of built-in function ‘malloc’

Solution

You need to add:

#include <stdlib.h>

This file includes the declaration for the built-in function malloc. If you don't do that, the compiler thinks you want to define your own function named malloc and it warns you because:

  1. You don't explicitly declare it and
  2. There already is a built-in function by that name which has a different signature than the one that was implicitly declared (when a function is declared implicitly, its return and argument types are assumed to be int, which isn't compatible with the built-in malloc, which takes a size_t and returns a void*).


Answered By - sepp2k
Answer Checked By - Willingham (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home
View mobile version

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing