Pages: [1]   Go Down
Author Topic: Wire.h mingles C++ and C  (Read 6152 times)
0 Members and 2 Guests are viewing this topic.
Belgium
Offline Offline
Edison Member
*
Karma: 68
Posts: 1897
Arduino rocks; but with my plugin it can fly rocking the world ;-)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi
I was trying to create a sketch in my eclipse environment in Arduino 1.0 using the wire library.
The compilation failed. Investigation pointed out that my eclipse plugin compiles all files as C++ files where the Arduino IDE has the compiler select the C or C++mode.
As a consequence of this twi.c is compiled as C code and wire.cpp is compiled as C++ code in the Arduino IDE. In my plugin they are both compiled as C++.
wire.cpp includes twi.h as follows:
Code:
extern "C" {
  #include <stdlib.h>
  #include <string.h>
  #include <inttypes.h>
  #include "twi.h"
}
where twi.c includes twi.h as follows:
Code:
#include "twi.h"
As a consequence twi.h is always compiled as C in the arduino IDE. However in the eclipse plugin it is compiled as C in wire.cpp an as C++ in twi.c.
I accept this can not be called a bug but I feel it would be nicer to change twi.h so that there is encapsulation of twi.h. (no need for extern "C" in wire.cpp). twi.h would look as follows:
Code:
/*
  twi.h - TWI/I2C library for Wiring & Arduino
  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#ifndef twi_h
#define twi_h

  #include <inttypes.h>

  //#define ATMEGA8

  #ifndef TWI_FREQ
  #define TWI_FREQ 100000L
  #endif

  #ifndef TWI_BUFFER_LENGTH
  #define TWI_BUFFER_LENGTH 32
  #endif

  #define TWI_READY 0
  #define TWI_MRX   1
  #define TWI_MTX   2
  #define TWI_SRX   3
  #define TWI_STX   4
#ifdef __cplusplus
extern "C" {
#endif
  void twi_init(void);
  void twi_setAddress(uint8_t);
  uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t);
  uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t);
  uint8_t twi_transmit(const uint8_t*, uint8_t);
  void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) );
  void twi_attachSlaveTxEvent( void (*)(void) );
  void twi_reply(uint8_t);
  void twi_stop(void);
  void twi_releaseBus(void);
#ifdef __cplusplus
 }
#endif

#endif


Could this be changed?
Best regards
Jantje
Logged

Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
As a consequence twi.h is always compiled as C in the arduino IDE. However in the eclipse plugin it is compiled as C in wire.cpp an as C++ in twi.c.
No. Header files are included in source files that are compiled. Header files by themselves are not compiled.
Logged

Guildford, UK
Offline Offline
Full Member
***
Karma: 0
Posts: 217
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
As a consequence twi.h is always compiled as C in the arduino IDE. However in the eclipse plugin it is compiled as C in wire.cpp an as C++ in twi.c.
No. Header files are included in source files that are compiled. Header files by themselves are not compiled.
However, ignoring terminology, the thrust of his argument, and the file changes he has proposed are correct.

extern "C" should only be used when the header is being included in a C++ source file.

Iain
Logged

Belgium
Offline Offline
Edison Member
*
Karma: 68
Posts: 1897
Arduino rocks; but with my plugin it can fly rocking the world ;-)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Paul
If it is not called "compiling" what the compiler does with the header file included in a *.c or *.cpp file during compilation; how  is it called?

Who can answer the question "Could this be changed?"

Jantje
Logged

Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

North Queensland, Australia
Offline Offline
Edison Member
*
Karma: 64
Posts: 2101
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

header file inclusion happens before compilation. It happens while/before the .cpp/.c is passed to the tokenizer
Logged


Seattle, WA
Offline Offline
God Member
*****
Karma: 11
Posts: 673
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Open an issue on the Arduino google code page.  Include a patch.

Doesn't make a lot of sense to change.  Arduino is geared toward the IDE not Eclipse, anyway.  You can always make the change locally and you're good.
Logged


SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 124
Posts: 6637
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
As a consequence of this twi.c is compiled as C code and wire.cpp is compiled as C++ code in the Arduino IDE. In my plugin they are both compiled as C++.

I think that makes your plugin broken.  Probably in easily fixable ways.  I don't think there's a reason to change .c files in the arduino distribution so that they compile even when treated as c++, even if that's possible.
Logged

Belgium
Offline Offline
Edison Member
*
Karma: 68
Posts: 1897
Arduino rocks; but with my plugin it can fly rocking the world ;-)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Maniacbug
Thanks for the link to the "open issue". I created one for this.
I agree it doesn't make much sense from an Arduino IDE point of view.
It is however hardly any work (I included the better  twi.h) and results in better code quality.

best regards
Jantje

PS I've found a way around it.
Logged

Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Christchurch
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What consequences does this issue have, does it cause problems at run time communicating with I2C devices?

Can you add a link to the issue you created for this, I cannot seem to find it.

thanks,
Chris
Logged

Belgium
Offline Offline
Edison Member
*
Karma: 68
Posts: 1897
Arduino rocks; but with my plugin it can fly rocking the world ;-)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Chris
The consequences are only visible for people writing their own tools on top of the Arduino library.
Basically you can not compile twi.c with the C++ compiler.
Further on I think it is a matter of taste on whether you prefer self containment and robustness or strict language layering (C code should not know about C++). Probably other arguments exist as well for both options.
Technically it is about the fact that C++ does name mangling and C does not. See http://en.wikipedia.org/wiki/Name_mangling for more info on name mangling.

You can easily find the ticked by following the create ticked link and searching for Wire.h

Best regards
Jantje
Logged

Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Offline Offline
Jr. Member
**
Karma: 1
Posts: 62
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I downloaded your plugin (1.2.5.5) and changed my default "twi.h" for you listed code. Unfortunately, I am still not able to compile my project since I receive this error messages:

Quote

**** Build of configuration Release for project WB_MCU1 ****

make all
Building file: /Applications/Arduino1.app/Contents/Resources/Java/libraries/Wire/utility/twi.c
Invoking: AVR Compiler
avr-gcc -I"/Applications/Arduino1.app/Contents/Resources/Java/hardware/arduino/cores/arduino" -I"/Applications/Arduino1.app/Contents/Resources/Java/hardware/arduino/variants/mega" -I"/Users/arduino/Documents/workspace/WB_MCU1" -I"/Users/arduino/Documents/Arduino1/libraries/RTClib" -I"/Applications/Arduino1.app/Contents/Resources/Java/libraries/Wire" -D__IN_ECLIPSE__=1 -DARDUINO=101 -DUSB_PID= -DUSB_VID= -Wall -Os -g -mmcu=atmega2560 -DF_CPU=16000000UL -MMD -MP -MF"Wire/utility/twi.d" -MT"Wire/utility/twi.d"  -c -o "Wire/utility/twi.o" "/Applications/Arduino1.app/Contents/Resources/Java/libraries/Wire/utility/twi.c"
/Applications/Arduino1.app/Contents/Resources/Java/libraries/Wire/utility/twi.c:115: error: conflicting types for 'twi_readFrom'
/Applications/Arduino1.app/Contents/Resources/Java/libraries/Wire/utility/twi.h:45: error: previous declaration of 'twi_readFrom' was here
/Applications/Arduino1.app/Contents/Resources/Java/libraries/Wire/utility/twi.c:192: error: conflicting types for 'twi_writeTo'
/Applications/Arduino1.app/Contents/Resources/Java/libraries/Wire/utility/twi.h:46: error: previous declaration of 'twi_writeTo' was here
make: *** [Wire/utility/twi.o] Error 1

**** Build Finished ****

My Wire.cpp tab has these lines with a bug sign:

uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop);

int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop);

Am I missing a step?

Thank you.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Globe,

I have the same probleme. I have also changed twi.h  according to the sugestion from Jantje.

Did you solve the problem?

Best regards

Georg

Logged

Pages: [1]   Go Up
Jump to: