espressif / arduino-esp32

Arduino core for the ESP32

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

WiFiClient and related macros - troubles when using forward declarations

cziter15 opened this issue · comments

Version

v3.0.1

Description

The classes related to networking, such as WiFiClient and WiFiServer, have been renamed to NetworkClient, NetworkServer, and similar names. To preserve backward compatibility, macros (defines) have been introduced, but they are embedded within the class headers.

This modification can create issues if you have utilized forward declarations in your headers. As a result, users are now compelled to include the full implementation in every instance.

A better approach would be to use inheritance rather than relying on defines.

class WiFiClient : public NetworkClient {};
  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

that would not work for return value of NetworkServer::accept()

@cziter15 can you provide a basic test?

Also I suggest you switch to NetworkClient when you detect Arduino 3. As @JAndrassy said, this will not work everywhere either.

that would not work for return value of NetworkServer::accept()

It's easy to trick it using fd() as we can pass fd() to underying implementation, but... there's WiFIClientSecure, which inherits from WiFiClient and this cannot be trivially handled, because of pointer-casting.

Looks like there's no solution to this. Even using #define is not a good idea.

Anyway, isn't it possible to define these "links" same way as ARDUINO macro?

Mhh, core 3.0.0 has breaking changes, why trying to be backwards compatible where it is not possible to do it correctly? Imho this is the wrong way. The user code needs to be adopted to the changes. Every "trickery" bites back some day...

Mhh, core 3.0.0 has breaking changes, why trying to be backwards compatible where it is not possible to do it correctly? Imho this is the wrong way. The user code needs to be adopted to the changes. Every "trickery" bites back some day...

I think it is possible, but it will require wrapper-like approach. Selective define inside header is bad, because it forces you to include the header - forward declaration is not possible.

@cziter15 did you see this comment by me-no-dev

@cziter15 can you provide a basic test?

Also I suggest you switch to NetworkClient when you detect Arduino 3.

In your CPP (should include Arduino.h or esp_arduino_version.h)

#if ESP_ARDUINO_VERSION_MAJOR >= 3
class NetworkClient;
#else
class WiFiClient;
#endif

Or

#if ESP_ARDUINO_VERSION_MAJOR >= 3
#define WiFiClient NetworkClient;
#endif

class WiFiClient;

In your CPP (should include Arduino.h or esp_arduino_version.h)

#if ESP_ARDUINO_VERSION_MAJOR >= 3
class NetworkClient;
#else
class WiFiClient;
#endif

Or

#if ESP_ARDUINO_VERSION_MAJOR >= 3
#define WiFiClient NetworkClient;
#endif

class WiFiClient;

I believe this is more of a consistency issue than a technical one. Current solution, which involves using macros in WiFiClient and other files, isn't ideal because it relies on the #define directive. The reason why the forward declaration isn't resolved remains unclear until one delves into the intricacies of the implementation.

In my opinion, the first approach is acceptable, but it should be complemented with an implementation in the .cpp file like this:

#if ESP_ARDUINO_VERSION_MAJOR >= 3
#include <NetworkClient.h>
#else
#include <WiFiClient.h>
#endif

A more effective (in context of #define) approach exists, as demonstrated by Microsoft. For instance, in the WinTypes.h file, only declarations and defines are included, without any method definitions. The actual method implementations are placed in separate files.

You can see an example of this in the WinTypes.h file on GitHub: WinTypes.h.

I feel that half-measures are being applied. In my opinion, either the definitions should be global (defined using compiler options, similar to the ESP32 or ARDUINO macros), or including the WiFiClient file should result in an error with a message like #error WiFiClient has been deprecated, please use NetworkClient instead.

@JAndrassy, I'm just discussing the issue and wondering if there's room for improvement. I've resolved it on my end by using global definitions, similar to the approach used in the WiFiClient header, but with -DWiFiClient=NetworkClient.

including the WiFiClient file should result in an error

How about a warning instead?

@me-no-dev Ah, yes, I was thinking of a warning. Busy day... :)

@me-no-dev warning will be issued only if the user included WiFiClient or related files directly. If using WiFi.h then it will remain unnoticed, but I don't have any idea in my mind on this.

The rest looks good for me.

@cziter15 try the latest changes please :) typedefs instead of defines

I think it's better to leave #define until future removal. I've spotted that typedef can generate ambiguity errors in my framework code (on esp8266 WiFiClient is under BearSLL namespace).