Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typedef'd nx types not usable as pass-by-value arguments #3

Open
jmattsson opened this issue Feb 14, 2013 · 0 comments
Open

Typedef'd nx types not usable as pass-by-value arguments #3

jmattsson opened this issue Feb 14, 2013 · 0 comments
Assignees

Comments

@jmattsson
Copy link

If I try to build an app with a function taking a typedef'd nx type as an argument, I get this error:

$ make micaz
mkdir -p build/micaz
compiling TestNxTypedefC to a micaz binary
ncc -o build/micaz/main.exe -Os -fnesc-separator=__ -Wall -Wshadow -Wnesc-all -target=micaz -fnesc-cfile=build/micaz/app.c -board=micasb -DDEFINED_TOS_AM_GROUP=0x22 --param max-inline-insns-single=100000 -DIDENT_APPNAME="TestNxTypedefC" -DIDENT_USERNAME="johny" -DIDENT_HOSTNAME="silence" -DIDENT_USERHASH=0x4027b159L -DIDENT_TIMESTAMP=0x5118d006L -DIDENT_UIDHASH=0x666c09d5L -fnesc-dump=wiring -fnesc-dump='interfaces(!abstract())' -fnesc-dump='referenced(interfacedefs, components)' -fnesc-dumpfile=build/micaz/wiring-check.xml TestNxTypedefC.nc -lm
TestNxTypedefP.nc:14:85: error: expected ‘)’ before ‘val’
TestNxTypedefP.nc:14:85: error: expected ‘)’ before ‘val’
TestNxTypedefP.nc: In function ‘TestNxTypedefP__Init__init’:
TestNxTypedefP.nc:21:3: warning: implicit declaration of function ‘TestNxTypedefP__foo’
make: *** [exe0] Error 1

Yet, if I simply change the typedef to a #define instead, the app compiles without even a warning. I thought it might be because I hadn't updated my toolchain (I was still using hinrg repo), but even after switching to tinyprod I get the same error.

I reduced this down to a minimal test app as follows:

==== Makefile ====

COMPONENT=TestNxTypedefC
include $(MAKERULES)

==== TestNxTypedefC ====

configuration TestNxTypedefC
{
}
implementation
{
components TestNxTypedefP, MainC;
MainC.SoftwareInit -> TestNxTypedefP;
}

==== TestNxTypedefP ====

module TestNxTypedefP
{
provides interface Init;
}
implementation
{

if 1

/* This fails */
typedef nx_uint16_t my_type16_t;

else

/* This works, ugly though it is */
#define my_type16_t nx_uint16_t

endif

error_t foo (my_type16_t val)
{
return (val == 1234) ? SUCCESS : FAIL;
}

command error_t Init.init (void)
{
return foo (1234);
}
}

First encountered with this toolchain:
$ ncc --version
ncc: 1.2.4
nescc: 1.3.1
gcc: gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 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.

Still encountered with this toolchain:
$ ncc --version
ncc: 1.4.2
nescc: 1.3.4
gcc: gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 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.

Looking at the generated app.c, I see this:

First there's the nx_uint16_t which is an innocuous enough packed struct:
typedef struct { unsigned char nxdata[2]; } attribute((packed)) nx_uint16_t;

Then there's an unused typedef of a __nesc_nxbase_nx_uint16_t whose use I'm not entirely clear on without delving into compiler internals:
typedef uint16_t __nesc_nxbase_nx_uint16_t ;

There is of course my typedef, looking as expected (module__type name):
typedef nx_uint16_t TestNxTypedefP__my_type16_t;

And then there's the weirdness of the function taking my typedef'd type as an argument:
static inline error_t TestNxTypedefP__foo(TestNxTypedefP____nesc_nxbase_my_type16_t val);

What I had expected to see here was:
static inline error_t TestNxTypedefP__foo(TestNxTypedefP__my_type16_t val);

It seems the compiler has an internal translation rule for nx types that translates them from the struct version to the "base" version when used as pass-by-value arguments. When compiling with the #define rather than the typedef, the function prototype looks like this:
static inline error_t TestNxTypedefP__foo(__nesc_nxbase_nx_uint16_t val);

At the very least the inability to typedef an nx type should be noted in the documentation, but of course ideally the typedef should just work.

Let me know if you need more information.

@ghost ghost assigned dgay42 Feb 14, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants