unit32_t size error in Code composer - code-composer

I am working on C++ based project where i am getting one error for below statement:
Code:
typedef char pb_static_assertion_UINT32_T_WRONG_SIZE3507__COUNTER__ [ ( sizeof ( uint32_t ) == 4 ) ? 1 : - 1 ] ; // The line at which i am getting error
Error:
"C:\Users\tkumar\Documents\LDRA\LDRAunit_C_CPP_9.7.1\trial\inszt_algctivationgateway.cpp", line 4330: error #95: the size of an array must be greater than zero"
Reference:
uint32_t is defined using:
typedef unsigned long uint32_t;
I have doubt for unsigned long size, anybody here to explain to tell me the reason behind this error ?

1) Code-Composer compiler outputs object in formats called COFF or EABI. When COFF was selected, unsigned long was 40-bits on for some of the microprocessors at least. When EABI was selected, it was 32-bits.
2) For some of the TI microprocessors, such as the C2000 series, the smallest addressable word was 16 bits, and sizeof would then output 2 instead of 4 for a 32-bit type.
3) One or the other of these is probably causing your sizeof statement to be returning something other than 4, causing ?: to select -1. So the array size is less than 0.
4) Don't think you really want an array after a typedef.

Related

Is ZeroMemory the windows equivalent of null terminating a buffer?

For example I by convention null terminate a buffer (set buffer equal to zero) the following way, example 1:
char buffer[1024] = {0};
And with the windows.h library we can call ZeroMemory, example 2:
char buffer[1024];
ZeroMemory(buffer, sizeof(buffer));
According to the documentation provided by microsoft: ZeroMemory Fills a block of memory with zeros. I want to be accurate in my windows application so I thought what better place to ask than stack overflow.
Are these two examples equivalent in logic?
Yes, the two codes are equivalent. The entire array is filled with zeros in both cases.
In the case of char buffer[1024] = {0};, you are explicitly setting only the first char element to 0, and then the compiler implicitly value-initializes the remaining 1023 char elements to 0 for you.
In C++11 and later, you can omit that first element value:
char buffer[1024] = {};
char buffer[1024]{};

How could SSCANF provide so strange results?

I am in 4-day fight with this code:
unsigned long baudrate = 0;
unsigned char databits = 0;
unsigned char stop_bits = 0;
char parity_text[10];
char flowctrl_text[4];
const char xformat[] = "%lu,%hhu,%hhu,%[^,],%[^,]\n";
const char xtext[] = "115200,8,1,EVEN,NFC\n";
int res = sscanf(xtext, xformat, &baudrate, &databits, &stop_bits, (char*) &parity_text, (char*) &flowctrl_text);
printf("Res: %d\r\n", res);
printf("baudrate: %lu, databits: %hhu, stop: %hhu, \r\n", baudrate, databits, stop_bits);
printf("parity: %s \r\n", parity_text);
printf("flowctrl: %s \r\n", flowctrl_text);
It returns:
Res: 5
baudrate: 115200, databits: 0, stop: 1,
parity:
flowctrl: NFC
Databits and parity missing !
Actually memory under the parity variable is '\0'VEN'\0',
looks like the first characters was somehow overwritten by sscanf procedure.
Return value of sscanf is 5, which suggests, that it was able to parse the input.
My configuration:
gccarmnoneeabi 7.2.1
Visual Studio Code 1.43.2
PlatformIO Core 4.3.1
PlatformIO Home 3.1.1
Lib ST-STM 6.0.0 (Mbed 5.14.1)
STM32F446RE (Nucleo-F446RE)
I have tried (without success):
compiling with mbed RTOS and without
variable types uint8_t, uint32_t
gccarm versions: 6.3.1, 8.3.1, 9.2.1
using another IDE (CLion+PlatformIO)
compiling on another computer (same config)
What actually helps:
making the variables static
compiling in Mbed online compiler
The behavior of sscanf is as whole very unpredictable, mixing the order or datatype of variables sometimes helps, but most often ends with another flaws in the output.
This took me longer than I care to admit. But like most issues it ended up being very simple.
char parity_text[10];
char flowctrl_text[4];
Needs to be changed to:
char parity_text[10] = {0};
char flowctrl_text[5] = {0};
The flowctrl_text array is not large enough at size four to hold "EVEN" and the NULL termination. If you bump it to a size of 5 you should have no problem. Just to be safe I would also initialize the arrays to 0.
Once I increased the size I had 0 issues with your existing code. Let me know if this helps.

How to make gcc/g++ warn on comparing signed and unsigned char

I have the following piece of code:
#include <stdlib.h>
#include <stdio.h>
void test(unsigned char * arg) { }
int main() {
char *pc = (char *) malloc(1);
unsigned char *pcu = (unsigned char *) malloc(1);
*pcu = *pc = -1; /* line 10 */
if (*pc == *pcu) puts("equal"); else puts("not equal"); /* line 12 */
pcu = pc; /* line 14 */
if (pcu == pc) { /* line 16 */
test(pc); /* line 18 */
}
return 0;
}
If I compile it with gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) (but it is not limited to this particular version) with options
gcc a.c -pedantic -Wall -Wextra -Wsign-conversion -Wno-unused-parameter; ./a.out
I get the following warnings
test.c: In function ‘main’:
test.c:10:21: warning: conversion to ‘unsigned char’ from ‘char’ may change the sign of the result [-Wsign-conversion]
test.c:14:13: warning: pointer targets in assignment differ in signedness [-Wpointer-sign]
test.c:16:17: warning: comparison of distinct pointer types lacks a cast [enabled by default]
test.c:18:17: warning: pointer targets in passing argument 1 of ‘test’ differ in signedness [-Wpointer-sign]
test.c:4:6: note: expected ‘unsigned char *’ but argument is of type ‘char *’
not equal
g++ warnings/errors are similar. I hope I understand why the comparison on line 12 is evaluated to false, but is there any way to get a warning also in such cases? If not, is there some principial difference between line 12 and the lines which cause warnings? Is there any specific reason why comparison of char and unsigned char shouldn't deserve its warning? Because at least at first glance, line 12 seems to me more "dangerous" than e.g. line 16.
A short "story behind": I have to put together pieces of code from various sources. Some of them use char and some of them use unsigned char. -funsigned-char would work fine, but I am forced to avoid it and rather to add proper type conversions. That's why such a warning would be useful for me, because now, if I forget to add a type conversion in such a case, the program silently fails.
Thanks in advance, P.
I believe this is caused by integer promotion.
When you deal with char or short, what C actually does (and this is defined by the standard, not the implementation) is promote those types to int before doing any operations. The theory, I think, is that int is supposed to be the natural size used by the underlying machine, and therefore the fastest, most efficient size; in fact, most architectures will do this conversion on loading a byte without being asked.
Since both signed char and unsigned char will fit happily within the range of a signed int, the compiler uses that for both, and the comparison becomes a pure signed comparison.
When you have a mismatched type on the left-hand-side of the expression (lines 10 and 14) then it needs to convert that back to the smaller type, but it can't, so you get a warning.
When you compared the mismatching pointers (line 16) and passed the mismatching pointer (line 18), the integer promotion is not in play because you never actually dereference the pointers, and so no integers are ever compared (char is an integer type also, of course).

warning: cast from pointer to integer of different size

I'm working on socket programming.. my code executes the way I want it to, I'm able to use it. BUT it gives me a warning on compilation.
I compile using
gcc server1.c -o server1 -lpthread
And I get the warning
warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
This error comes for the following code
int newsockfd;
newsockfd = (int)newsockfdd; //this line
And I'm using newsockfdd (which is int) in the following chunk of code
if (pthread_create(&threadID[i++], NULL, serverThread, (void *)(intptr_t)newsockfdd) != 0)
{
perror("Thread create error");
}
As you can probably tell, the code is not written too well (I am working on making it better). I know that this warning comes because of something to do with the size of int. But I really dunno how to fix it. Before I put in (intptr_t) in the pthread_create statement, it was showing a warning on that line, but that time the warning was
warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
It seems like there should be a simple fix to this? But I can't find it. I'm using Ubuntu 64-bit. Is that a reason for the warning?
As has been established in the comments, the situation is (modulo renaming to avoid confusing occurrences of newsockfdd as passed argument or received parameter)
void *serverThread(void *arg) {
// ...
int newsockfd = (int)arg;
// ...
}
and in main (or a function called from there)
// ...
int newsockfdd = whatever;
// ...
if (pthread_create(&threadID[i++], NULL, serverThread, (void *)(intptr_t)newsockfdd) != 0)
// ..
So when the int newsockfdd is passed as an argument to serverThread, it is cast to a void*. Originally, that cast was direct, but the intermediate cast to intptr_t was inserted to remove the warning about the cast to pointer from integer of different size.
And in serverThread, the received void* is cast to int, resulting in the warning about the cast from pointer to integer of different size.
That warning could probably also be removed by inserting an intermediate cast to intptr_t.
But, while the standard allows casting integers to pointers and vice versa, the results are implementation-defined and there's no guarantee that int -> void* -> int round-trips (although, a footnote in the standard says
The mapping functions for converting a pointer to an integer or an integer to a pointer are intended to
be consistent with the addressing structure of the execution environment.
so probably it will round-trip and work as intended in this case - but it would likely not work [only for values of small enough absolute value] if the size of a void* is smaller than that of the integer type [consider long long -> void* -> long long on 32-bit systems]).
The proper fix is to avoid the casting between integers and pointers,
void *serverThread(void *arg) {
// ... check that arg isn't NULL
int newsockfd = *(int *)arg;
// ...
}
in severThread, cast the received pointer to a pointer of appropriate type, and read the pointed-to value, and in main
if// ...
int newsockfdd = whatever;
// ...
if (pthread_create(&threadID[i++], NULL, serverThread, &newsockfdd) != 0)
pass the address of newsockfdd.
One caveat: if serverThread is called from multiple places, the calls in all these places need to be fixed.

Setting register values in PIC16F876 using Hi Tech PICC

I am using MPLABx and the HI Tech PICC compiler. My target chip is a PIC16F876. By looking at the pic16f876.h include file, it appears that it should be possible to set the system registers of the chip by referring to them by name.
For example, within the CCP1CON register, bits 0 to 3 set how the CCP and PWM modules work. By looking at the pic16f876.h file, it looks like it should be possible to refer to these 4 bits alone, without change the value of the rest of the CCP1CON register.
However, I have tried to refer to these 4 bits in a variety of ways with no success.
I have tried;
CCP1CON.CCP1M=0xC0; this results in "error: struct/union required
CCP1CON:CCP1M=0xC0; this results in "error: undefined identifier "CCP1M"
but both have failed. I have read through the Hi Tech PICC compiler manual, but cannot see how to do this.
From the pic16f876.h file, it looks to me as though I should be able to refer to these subsets within the system registers by name, as they are defined in the .h file.
Does anyone know how to accomplish this?
Excerpt from pic16f876.h
// Register: CCP1CON
volatile unsigned char CCP1CON # 0x017;
// bit and bitfield definitions
volatile bit CCP1Y # ((unsigned)&CCP1CON*8)+4;
volatile bit CCP1X # ((unsigned)&CCP1CON*8)+5;
volatile bit CCP1M0 # ((unsigned)&CCP1CON*8)+0;
volatile bit CCP1M1 # ((unsigned)&CCP1CON*8)+1;
volatile bit CCP1M2 # ((unsigned)&CCP1CON*8)+2;
volatile bit CCP1M3 # ((unsigned)&CCP1CON*8)+3;
#ifndef _LIB_BUILD
volatile union {
struct {
unsigned CCP1M : 4;
unsigned CCP1Y : 1;
unsigned CCP1X : 1;
};
struct {
unsigned CCP1M0 : 1;
unsigned CCP1M1 : 1;
unsigned CCP1M2 : 1;
unsigned CCP1M3 : 1;
};
} CCP1CONbits # 0x017;
#endif
You need to access the bitfield members through an instance of a struct. In this case, that is CCP1CONbits. Because it is a bitfield, you only need to have the number of significant bits as defined in the bitfield, not the full eight bits in your code.
So:
CCP1CONbits.CCP1M = 0x0c;
Should be the equivalent of what you are trying to do. If you want to set all eight bits at once you can use CCP1CON = 0xc0. That would set the CCP1M bits to 0x0c and all the other bits to zero.
The header you gave also has individual bit symbols, so you could do this too:
CCP1M0 = 1;
CCP1M1 = 1;
CCP1M2 = 0;
CCP1M3 = 0;
Although the bitfield approach is cleaner.

Resources